summaryrefslogtreecommitdiffstats
path: root/lib/kofficeui
diff options
context:
space:
mode:
authortpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-01-20 01:29:50 +0000
committertpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-01-20 01:29:50 +0000
commit8362bf63dea22bbf6736609b0f49c152f975eb63 (patch)
tree0eea3928e39e50fae91d4e68b21b1e6cbae25604 /lib/kofficeui
downloadkoffice-8362bf63dea22bbf6736609b0f49c152f975eb63.tar.gz
koffice-8362bf63dea22bbf6736609b0f49c152f975eb63.zip
Added old abandoned KDE3 version of koffice
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/koffice@1077364 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'lib/kofficeui')
-rw-r--r--lib/kofficeui/KoBrush.cpp64
-rw-r--r--lib/kofficeui/KoBrush.h106
-rw-r--r--lib/kofficeui/KoCharSelectDia.cpp116
-rw-r--r--lib/kofficeui/KoCharSelectDia.h76
-rw-r--r--lib/kofficeui/KoCommandHistory.cpp446
-rw-r--r--lib/kofficeui/KoCommandHistory.h198
-rw-r--r--lib/kofficeui/KoContextCelp.cpp595
-rw-r--r--lib/kofficeui/KoContextCelp.h279
-rw-r--r--lib/kofficeui/KoEditPath.cpp98
-rw-r--r--lib/kofficeui/KoEditPath.h55
-rw-r--r--lib/kofficeui/KoGeneralPropertyUi.ui193
-rw-r--r--lib/kofficeui/KoGuideLineDia.cpp131
-rw-r--r--lib/kofficeui/KoGuideLineDia.h96
-rw-r--r--lib/kofficeui/KoGuides.cpp926
-rw-r--r--lib/kofficeui/KoGuides.h421
-rw-r--r--lib/kofficeui/KoImageResource.cpp117
-rw-r--r--lib/kofficeui/KoImageResource.h38
-rw-r--r--lib/kofficeui/KoInsertLink.cpp549
-rw-r--r--lib/kofficeui/KoInsertLink.h148
-rw-r--r--lib/kofficeui/KoKoolBar.cpp489
-rw-r--r--lib/kofficeui/KoKoolBar.h166
-rw-r--r--lib/kofficeui/KoPageLayoutColumns.cpp70
-rw-r--r--lib/kofficeui/KoPageLayoutColumns.h75
-rw-r--r--lib/kofficeui/KoPageLayoutColumnsBase.ui99
-rw-r--r--lib/kofficeui/KoPageLayoutDia.cpp402
-rw-r--r--lib/kofficeui/KoPageLayoutDia.h200
-rw-r--r--lib/kofficeui/KoPageLayoutHeader.cpp73
-rw-r--r--lib/kofficeui/KoPageLayoutHeader.h56
-rw-r--r--lib/kofficeui/KoPageLayoutHeaderBase.ui221
-rw-r--r--lib/kofficeui/KoPageLayoutSize.cpp350
-rw-r--r--lib/kofficeui/KoPageLayoutSize.h118
-rw-r--r--lib/kofficeui/KoPartSelectAction.cpp80
-rw-r--r--lib/kofficeui/KoPartSelectAction.h57
-rw-r--r--lib/kofficeui/KoPartSelectDia.cpp93
-rw-r--r--lib/kofficeui/KoPartSelectDia.h70
-rw-r--r--lib/kofficeui/KoPen.cpp69
-rw-r--r--lib/kofficeui/KoPen.h68
-rw-r--r--lib/kofficeui/KoPictureFilePreview.cpp121
-rw-r--r--lib/kofficeui/KoPictureFilePreview.h67
-rw-r--r--lib/kofficeui/KoRuler.cpp1202
-rw-r--r--lib/kofficeui/KoRuler.h372
-rw-r--r--lib/kofficeui/KoSelectAction.cpp193
-rw-r--r--lib/kofficeui/KoSelectAction.h90
-rw-r--r--lib/kofficeui/KoTabBar.cpp913
-rw-r--r--lib/kofficeui/KoTabBar.h275
-rw-r--r--lib/kofficeui/KoTabChooser.cpp175
-rw-r--r--lib/kofficeui/KoTabChooser.h80
-rw-r--r--lib/kofficeui/KoTemplateChooseDia.cpp829
-rw-r--r--lib/kofficeui/KoTemplateChooseDia.h250
-rw-r--r--lib/kofficeui/KoTemplateCreateDia.cpp497
-rw-r--r--lib/kofficeui/KoTemplateCreateDia.h75
-rw-r--r--lib/kofficeui/KoToolBox.cpp256
-rw-r--r--lib/kofficeui/KoToolBox.h119
-rw-r--r--lib/kofficeui/KoTooluButton.cpp858
-rw-r--r--lib/kofficeui/KoTooluButton.h183
-rw-r--r--lib/kofficeui/KoUnitWidgets.cpp455
-rw-r--r--lib/kofficeui/KoUnitWidgets.h246
-rw-r--r--lib/kofficeui/KoZoomAction.cpp115
-rw-r--r--lib/kofficeui/KoZoomAction.h82
-rw-r--r--lib/kofficeui/KoZoomHandler.cpp72
-rw-r--r--lib/kofficeui/KoZoomHandler.h163
-rw-r--r--lib/kofficeui/KoZoomMode.cpp49
-rw-r--r--lib/kofficeui/KoZoomMode.h54
-rw-r--r--lib/kofficeui/Kolinestyleaction.cpp88
-rw-r--r--lib/kofficeui/Kolinestyleaction.h58
-rw-r--r--lib/kofficeui/Kolinewidthaction.cpp200
-rw-r--r--lib/kofficeui/Kolinewidthaction.h112
-rw-r--r--lib/kofficeui/Makefile.am61
-rw-r--r--lib/kofficeui/kcoloractions.cpp348
-rw-r--r--lib/kofficeui/kcoloractions.h101
-rw-r--r--lib/kofficeui/koffice.widgets32
-rw-r--r--lib/kofficeui/pics/Makefile.am12
-rw-r--r--lib/kofficeui/pics/koKoolBarDown.pngbin0 -> 398 bytes
-rw-r--r--lib/kofficeui/pics/koKoolBarUp.pngbin0 -> 399 bytes
-rw-r--r--lib/kofficeui/pics/koLandscape.pngbin0 -> 883 bytes
-rw-r--r--lib/kofficeui/pics/koPortrait.pngbin0 -> 890 bytes
-rw-r--r--lib/kofficeui/pics/koRulerFirst.pngbin0 -> 191 bytes
-rw-r--r--lib/kofficeui/pics/koRulerLeft.pngbin0 -> 201 bytes
-rw-r--r--lib/kofficeui/pics/koffice-logo.pngbin0 -> 10988 bytes
-rw-r--r--lib/kofficeui/pics/kounitdoublecombobox.pngbin0 -> 1211 bytes
-rw-r--r--lib/kofficeui/pics/kounitdoublelineedit.pngbin0 -> 1169 bytes
-rw-r--r--lib/kofficeui/pics/kounitdoublespinbox2.pngbin0 -> 832 bytes
-rw-r--r--lib/kofficeui/pics/kounitdoublespincombobox.pngbin0 -> 1211 bytes
-rw-r--r--lib/kofficeui/tests/Makefile.am15
-rw-r--r--lib/kofficeui/tests/coloraction_test.cpp112
-rw-r--r--lib/kofficeui/tests/coloraction_test.h44
-rw-r--r--lib/kofficeui/tkaction.cpp300
-rw-r--r--lib/kofficeui/tkaction.h123
-rw-r--r--lib/kofficeui/tkcoloractions.cpp621
-rw-r--r--lib/kofficeui/tkcoloractions.h169
-rw-r--r--lib/kofficeui/tkcombobox.cpp123
-rw-r--r--lib/kofficeui/tkcombobox.h41
-rw-r--r--lib/kofficeui/tktoolbarbutton.cpp532
-rw-r--r--lib/kofficeui/tktoolbarbutton.h227
94 files changed, 18518 insertions, 0 deletions
diff --git a/lib/kofficeui/KoBrush.cpp b/lib/kofficeui/KoBrush.cpp
new file mode 100644
index 00000000..62b3fa96
--- /dev/null
+++ b/lib/kofficeui/KoBrush.cpp
@@ -0,0 +1,64 @@
+// -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4; -*-
+/* This file is part of the KDE project
+ Copyright (C) 2005-2006 Thorsten Zachmann <zachmann@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#include "KoBrush.h"
+
+#include <KoGenStyles.h>
+#include <KoXmlNS.h>
+
+KoBrush::KoBrush()
+: m_gColor1( Qt::red )
+, m_gColor2( Qt::green )
+, m_gType( BCT_GHORZ )
+, m_fillType( FT_BRUSH )
+, m_unbalanced( false )
+, m_xfactor( 100 )
+, m_yfactor( 100 )
+{
+}
+
+
+KoBrush::KoBrush( const QBrush &brush, const QColor &gColor1, const QColor &gColor2,
+ BCType gType, FillType fillType, bool unbalanced,
+ int xfactor, int yfactor )
+: m_brush( brush )
+, m_gColor1( gColor1 )
+, m_gColor2( gColor2 )
+, m_gType( gType )
+, m_fillType( fillType )
+, m_unbalanced( unbalanced )
+, m_xfactor( xfactor )
+, m_yfactor( yfactor )
+{
+}
+
+
+KoBrush & KoBrush::operator=( const KoBrush &brush )
+{
+ m_brush = brush.m_brush;
+ m_gColor1 = brush.m_gColor1;
+ m_gColor2 = brush.m_gColor2;
+ m_gType = brush.m_gType;
+ m_fillType = brush.m_fillType;
+ m_unbalanced = brush.m_unbalanced;
+ m_xfactor = brush.m_xfactor;
+ m_yfactor = brush.m_yfactor;
+ return *this;
+}
diff --git a/lib/kofficeui/KoBrush.h b/lib/kofficeui/KoBrush.h
new file mode 100644
index 00000000..142dbb92
--- /dev/null
+++ b/lib/kofficeui/KoBrush.h
@@ -0,0 +1,106 @@
+// -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4; -*-
+/* This file is part of the KDE project
+ Copyright (C) 2005-2006 Thorsten Zachmann <zachmann@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KOBRUSH_H
+#define KOBRUSH_H
+
+#include <qbrush.h>
+
+class KoGenStyle;
+class KoGenStyles;
+class KoOasisContext;
+class QDomElement;
+
+
+enum BCType {
+ BCT_PLAIN = 0,
+ BCT_GHORZ = 1,
+ BCT_GVERT = 2,
+ BCT_GDIAGONAL1 = 3,
+ BCT_GDIAGONAL2 = 4,
+ BCT_GCIRCLE = 5,
+ BCT_GRECT = 6,
+ BCT_GPIPECROSS = 7,
+ BCT_GPYRAMID = 8
+};
+
+enum FillType
+{
+ FT_BRUSH = 0,
+ FT_GRADIENT = 1
+};
+
+class KoBrush
+{
+public:
+ KoBrush();
+ KoBrush( const QBrush &brush, const QColor &gColor1, const QColor &gColor2,
+ BCType gType, FillType fillType, bool unbalanced,
+ int xfactor, int yfactor );
+
+ KoBrush &operator=( const KoBrush &brush );
+
+ void setBrush( const QBrush &brush )
+ { m_brush = brush; }
+ void setGColor1( const QColor &gColor1 )
+ { m_gColor1 = gColor1; }
+ void setGColor2( const QColor &gColor2 )
+ { m_gColor2 = gColor2; }
+ void setGType( BCType gType )
+ { m_gType = gType; }
+ void setFillType( FillType fillType )
+ { m_fillType = fillType; }
+ void setGUnbalanced( bool unbalanced )
+ { m_unbalanced = unbalanced; }
+ void setGXFactor( int xfactor )
+ { m_xfactor = xfactor; }
+ void setGYFactor( int yfactor )
+ { m_yfactor = yfactor; }
+
+ QBrush getBrush() const
+ { return m_brush; }
+ QColor getGColor1() const
+ { return m_gColor1; }
+ QColor getGColor2() const
+ { return m_gColor2; }
+ BCType getGType() const
+ { return m_gType; }
+ FillType getFillType() const
+ { return m_fillType; }
+ bool getGUnbalanced() const
+ { return m_unbalanced; }
+ int getGXFactor() const
+ { return m_xfactor; }
+ int getGYFactor() const
+ { return m_yfactor; }
+
+private:
+ QBrush m_brush;
+ QColor m_gColor1;
+ QColor m_gColor2;
+ BCType m_gType;
+ FillType m_fillType;
+ bool m_unbalanced;
+ int m_xfactor;
+ int m_yfactor;
+};
+
+#endif /* KOBRUSH_H */
+
diff --git a/lib/kofficeui/KoCharSelectDia.cpp b/lib/kofficeui/KoCharSelectDia.cpp
new file mode 100644
index 00000000..5a0105c6
--- /dev/null
+++ b/lib/kofficeui/KoCharSelectDia.cpp
@@ -0,0 +1,116 @@
+/* This file is part of the KDE project
+ Copyright (C) 1998, 1999 Reginald Stadlbauer <reggie@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#include "KoCharSelectDia.h"
+#include "KoCharSelectDia.moc"
+
+#include <qlayout.h>
+
+#include <klocale.h>
+#include <kcharselect.h>
+#include <kdebug.h>
+/******************************************************************/
+/* class KoCharSelectDia */
+/******************************************************************/
+
+KoCharSelectDia::KoCharSelectDia( QWidget *parent, const char *name, const QChar &_chr, const QString &_font, bool _enableFont , bool _modal)
+ : KDialogBase( Plain, i18n("Select Character"), Ok | Cancel, Ok , parent, name, _modal )
+{
+ initDialog(_chr,_font,_enableFont);
+
+ KGuiItem okItem = KStdGuiItem::ok(); // start from std item to keep the OK icon...
+ okItem.setText( i18n("&Insert") );
+ okItem.setWhatsThis( i18n("Insert the selected character in the text") );
+ setButtonOK( okItem );
+}
+
+KoCharSelectDia::KoCharSelectDia( QWidget *parent, const char *name, const QString &_font, const QChar &_chr, bool _modal )
+ : KDialogBase( Plain, i18n("Select Character"), User1 | Close, User1 , parent, name, _modal )
+{
+ initDialog(_chr,_font,true);
+
+ setButtonText( User1, i18n("&Insert") );
+ setButtonTip( User1, i18n("Insert the selected character in the text") );
+
+}
+
+void KoCharSelectDia::initDialog(const QChar &_chr, const QString &_font, bool /*_enableFont*/)
+{
+ QWidget *page = plainPage();
+
+ grid = new QGridLayout( page, 1, 1, 0, KDialog::spacingHint() );
+
+ charSelect = new KCharSelect( page, "", _font, _chr );
+ connect(charSelect, SIGNAL(doubleClicked()),this, SLOT(slotDoubleClicked()));
+ charSelect->resize( charSelect->sizeHint() );
+ charSelect->enableFontCombo( true );
+ grid->addWidget( charSelect, 0, 0 );
+
+ grid->addColSpacing( 0, charSelect->width() );
+ grid->addRowSpacing( 0, charSelect->height() );
+ grid->setRowStretch( 0, 0 );
+ charSelect->setFocus();
+}
+
+KoCharSelectDia::~KoCharSelectDia()
+{
+}
+
+void KoCharSelectDia::closeDialog()
+{
+ KDialogBase::close();
+}
+
+bool KoCharSelectDia::selectChar( QString &_font, QChar &_chr, bool _enableFont, QWidget* parent, const char* name )
+{
+ bool res = false;
+
+ KoCharSelectDia *dlg = new KoCharSelectDia( parent, name, _chr, _font, _enableFont );
+ dlg->setFocus();
+ if ( dlg->exec() == Accepted )
+ {
+ _font = dlg->font();
+ _chr = dlg->chr();
+ res = true;
+ }
+
+ delete dlg;
+
+ return res;
+}
+
+QChar KoCharSelectDia::chr() const
+{
+ return charSelect->chr();
+}
+
+QString KoCharSelectDia::font() const
+{
+ return charSelect->font();
+}
+
+void KoCharSelectDia::slotUser1()
+{
+ emit insertChar(chr(),font());
+}
+
+void KoCharSelectDia::slotDoubleClicked()
+{
+ emit insertChar(chr(),font());
+}
diff --git a/lib/kofficeui/KoCharSelectDia.h b/lib/kofficeui/KoCharSelectDia.h
new file mode 100644
index 00000000..dba5e76e
--- /dev/null
+++ b/lib/kofficeui/KoCharSelectDia.h
@@ -0,0 +1,76 @@
+/* This file is part of the KDE project
+ Copyright (C) 1998, 1999 Reginald Stadlbauer <reggie@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KOCHARSELECTDIA_H
+#define KOCHARSELECTDIA_H
+
+#include <kdialogbase.h>
+#include <koffice_export.h>
+
+class QWidget;
+class QGridLayout;
+class QPushButton;
+class KCharSelect;
+class KButtonBox;
+
+/******************************************************************/
+/* class KoCharSelectDia */
+/******************************************************************/
+
+class KOFFICEUI_EXPORT KoCharSelectDia : public KDialogBase
+{
+ Q_OBJECT
+
+public:
+
+ // constructor - destructor
+ KoCharSelectDia( QWidget *parent, const char *name, const QChar &_chr,
+ const QString &_font, bool _enableFont, bool _modal=true );
+
+ //constructor when you want to insert multi char
+ KoCharSelectDia( QWidget *parent, const char *name, const QString &_font,
+ const QChar &_chr, bool _modal=true );
+ ~KoCharSelectDia();
+ // select char dialog
+ KOFFICEUI_EXPORT static bool selectChar( QString &_font, QChar &_chr, bool _enableFont = true, QWidget* parent = 0, const char* name = 0);
+
+ // internal
+ QChar chr() const;
+ QString font() const;
+ void closeDialog();
+
+private:
+ void initDialog(const QChar &_chr, const QString &_font, bool _enableFont);
+
+private slots:
+ void slotUser1();
+ void slotDoubleClicked();
+
+protected:
+ // dialog objects
+ QGridLayout *grid;
+ KButtonBox *bbox;
+ QPushButton *bOk, *bCancel;
+ KCharSelect *charSelect;
+
+ signals:
+ void insertChar(QChar,const QString &);
+};
+
+#endif
diff --git a/lib/kofficeui/KoCommandHistory.cpp b/lib/kofficeui/KoCommandHistory.cpp
new file mode 100644
index 00000000..79f0a14f
--- /dev/null
+++ b/lib/kofficeui/KoCommandHistory.cpp
@@ -0,0 +1,446 @@
+/* This file is part of the KDE project
+ Copyright (C) 2000 Werner Trobin <trobin@kde.org>
+ Copyright (C) 2000 David Faure <faure@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qlistbox.h>
+
+#include <kaction.h>
+#include <kcommand.h>
+#include <kdebug.h>
+#include <klocale.h>
+#include <kpopupmenu.h>
+#include <kshortcutlist.h>
+#include <kstdaccel.h>
+#include <kstdaction.h>
+
+#include "KoCommandHistory.h"
+
+KoListBox::KoListBox( QWidget *parent , const char *name , WFlags f)
+ : QListBox( parent, name, f)
+{
+ setVScrollBarMode( AlwaysOn );
+}
+
+void KoListBox::contentsMouseMoveEvent ( QMouseEvent * e)
+{
+ QListBoxItem *item_p = itemAt( contentsToViewport(e->pos()));
+ if ( item_p )
+ {
+ int itemIndex = index( item_p );
+ for ( int i = 0; i<=itemIndex;i++)
+ setSelected ( i, true );
+ for ( int i = itemIndex+1; i<(int)count();i++)
+ setSelected ( i, false );
+ emit changeNumberOfSelectedItem( itemIndex);
+ }
+}
+
+QSize KoListBox::sizeHint() const
+{
+ return QSize(QMIN(maxItemWidth() + verticalScrollBar()->width() + 4, 400),
+ QMIN(count() * itemHeight() + horizontalScrollBar()->height() + 4,300));
+}
+
+class KoCommandHistory::KoCommandHistoryPrivate {
+public:
+ KoCommandHistoryPrivate() {
+ m_savedAt=-1;
+ m_present=0;
+ }
+ ~KoCommandHistoryPrivate() {}
+ int m_savedAt;
+ KCommand *m_present;
+ KoListBox *m_undoListBox;
+ KoListBox *m_redoListBox;
+ QLabel *m_undoLabel;
+ QLabel *m_redoLabel;
+};
+
+////////////
+
+KoCommandHistory::KoCommandHistory() :
+ m_undo(0), m_redo(0), m_undoLimit(50), m_redoLimit(30), m_first(false)
+{
+ d=new KoCommandHistoryPrivate();
+ m_commands.setAutoDelete(true);
+ clear();
+}
+
+KoCommandHistory::KoCommandHistory(KActionCollection * actionCollection, bool withMenus) :
+ m_undoLimit(50), m_redoLimit(30), m_first(false)
+{
+ d=new KoCommandHistoryPrivate();
+ if (withMenus)
+ {
+ KToolBarPopupAction * undo = new KToolBarPopupAction( i18n("&Undo"), "undo",
+ KStdAccel::undo(), this, SLOT( undo() ),
+ actionCollection, /*KStdAction::stdName( KStdAction::Undo )*/"koffice_undo" );
+ connect( undo->popupMenu(), SIGNAL( aboutToShow() ), this, SLOT( slotUndoAboutToShow() ) );
+ connect( undo->popupMenu(), SIGNAL( activated( int ) ), this, SLOT( slotUndoActivated( int ) ) );
+ m_undo = undo;
+ m_undoPopup = undo->popupMenu();
+ d->m_undoListBox = new KoListBox( m_undoPopup );
+ d->m_undoListBox->setSelectionMode( QListBox::Multi );
+
+ m_undoPopup->insertItem(d->m_undoListBox);
+ d->m_undoLabel = new QLabel( m_undoPopup);
+ m_undoPopup->insertItem(d->m_undoLabel);
+
+ connect( d->m_undoListBox, SIGNAL( selected( int ) ), this, SLOT( slotUndoActivated( int ) ) );
+ connect( d->m_undoListBox, SIGNAL(clicked ( QListBoxItem *)), this, SLOT( slotUndoActivated( QListBoxItem * ) ) );
+
+ connect( d->m_undoListBox, SIGNAL( changeNumberOfSelectedItem( int )), this, SLOT( slotChangeUndoNumberOfSelectedItem( int )));
+
+ KToolBarPopupAction * redo = new KToolBarPopupAction( i18n("&Redo"), "redo",
+ KStdAccel::redo(), this, SLOT( redo() ),
+ actionCollection, /*KStdAction::stdName( KStdAction::Redo )*/
+ "koffice_redo");
+ connect( redo->popupMenu(), SIGNAL( aboutToShow() ), this, SLOT( slotRedoAboutToShow() ) );
+ connect( redo->popupMenu(), SIGNAL( activated( int ) ), this, SLOT( slotRedoActivated( int ) ) );
+ m_redo = redo;
+ m_redoPopup = redo->popupMenu();
+ d->m_redoListBox = new KoListBox( m_redoPopup );
+ d->m_redoListBox->setSelectionMode( QListBox::Multi );
+ m_redoPopup->insertItem(d->m_redoListBox);
+
+ d->m_redoLabel = new QLabel( m_redoPopup);
+ m_redoPopup->insertItem(d->m_redoLabel);
+
+
+ connect( d->m_redoListBox, SIGNAL( selected( int ) ), this, SLOT( slotRedoActivated( int ) ) );
+ connect( d->m_redoListBox, SIGNAL(clicked ( QListBoxItem *)), this, SLOT( slotRedoActivated( QListBoxItem * ) ) );
+ connect( d->m_redoListBox, SIGNAL( changeNumberOfSelectedItem( int )), this, SLOT( slotChangeRedoNumberOfSelectedItem( int )));
+
+ }
+ else
+ {
+ m_undo = KStdAction::undo( this, SLOT( undo() ), actionCollection, "koffice_undo");
+ m_redo = KStdAction::redo( this, SLOT( redo() ), actionCollection, "koffice_redo");
+ m_undoPopup = 0L;
+ m_redoPopup = 0L;
+ d->m_redoListBox = 0L;
+ d->m_undoListBox = 0L;
+ d->m_redoLabel = 0L;
+ d->m_undoLabel = 0L;
+ }
+ m_commands.setAutoDelete(true);
+ clear();
+}
+
+KoCommandHistory::~KoCommandHistory() {
+ delete d;
+}
+
+KCommand * KoCommandHistory::presentCommand ( )
+{ return d->m_present;
+}
+
+
+void KoCommandHistory::clear() {
+ if (m_undo != 0) {
+ m_undo->setEnabled(false);
+ m_undo->setText(i18n("&Undo"));
+ }
+ if (m_redo != 0) {
+ m_redo->setEnabled(false);
+ m_redo->setText(i18n("&Redo"));
+ }
+ d->m_present = 0L;
+ d->m_savedAt=-42;
+}
+
+void KoCommandHistory::addCommand(KCommand *command, bool execute) {
+
+ if(command==0L)
+ return;
+
+ int index;
+ if(d->m_present!=0L && (index=m_commands.findRef(d->m_present))!=-1) {
+ if (m_first)
+ --index;
+ m_commands.insert(index+1, command);
+ // truncate history
+ unsigned int count=m_commands.count();
+ for(unsigned int i=index+2; i<count; ++i)
+ m_commands.removeLast();
+ // check whether we still can reach savedAt
+ if(index<d->m_savedAt)
+ d->m_savedAt=-1;
+ d->m_present=command;
+ m_first=false;
+ if (m_undo != 0) {
+ m_undo->setEnabled(true);
+ m_undo->setText(i18n("&Undo: %1").arg(d->m_present->name()));
+ }
+ if((m_redo != 0) && m_redo->isEnabled()) {
+ m_redo->setEnabled(false);
+ m_redo->setText(i18n("&Redo"));
+ }
+ clipCommands();
+ }
+ else { // either this is the first time we add a Command or something has gone wrong
+ kdDebug(230) << "KoCommandHistory: Initializing the Command History" << endl;
+ m_commands.clear();
+ m_commands.append(command);
+ d->m_present=command;
+ if (m_undo != 0) {
+ m_undo->setEnabled(true);
+ m_undo->setText(i18n("&Undo: %1").arg(d->m_present->name()));
+ }
+ if (m_redo != 0) {
+ m_redo->setEnabled(false);
+ m_redo->setText(i18n("&Redo"));
+ }
+ m_first=false; // Michael B: yes, that *is* correct :-)
+ }
+ if ( execute )
+ {
+ command->execute();
+ emit commandExecuted();
+ emit commandExecuted(command);
+ }
+}
+
+void KoCommandHistory::undo() {
+
+ if (m_first || (d->m_present == 0L))
+ return;
+
+ d->m_present->unexecute();
+ KCommand *commandUndone = d->m_present;
+
+ if (m_redo != 0) {
+ m_redo->setEnabled(true);
+ m_redo->setText(i18n("&Redo: %1").arg(d->m_present->name()));
+ }
+ int index;
+ if((index=m_commands.findRef(d->m_present))!=-1 && m_commands.prev()!=0) {
+ d->m_present=m_commands.current();
+ emit commandExecuted();
+ emit commandExecuted(commandUndone);
+ if (m_undo != 0) {
+ m_undo->setEnabled(true);
+ m_undo->setText(i18n("&Undo: %1").arg(d->m_present->name()));
+ }
+ --index;
+ if(index==d->m_savedAt)
+ emit documentRestored();
+ }
+ else {
+ emit commandExecuted();
+ emit commandExecuted(commandUndone);
+ if (m_undo != 0) {
+ m_undo->setEnabled(false);
+ m_undo->setText(i18n("&Undo"));
+ }
+ if(d->m_savedAt==-42)
+ emit documentRestored();
+ m_first=true;
+ }
+ clipCommands(); // only needed here and in addCommand, NOT in redo
+}
+
+void KoCommandHistory::redo() {
+
+ int index;
+ if(m_first) {
+ d->m_present->execute();
+ emit commandExecuted();
+ emit commandExecuted(d->m_present);
+ m_first=false;
+ m_commands.first();
+ if(d->m_savedAt==0)
+ emit documentRestored();
+ }
+ else if((index=m_commands.findRef(d->m_present))!=-1 && m_commands.next()!=0) {
+ d->m_present=m_commands.current();
+ d->m_present->execute();
+ emit commandExecuted();
+ emit commandExecuted(d->m_present);
+ ++index;
+ if(index==d->m_savedAt)
+ emit documentRestored();
+ }
+
+ if (m_undo != 0) {
+ m_undo->setEnabled(true);
+ m_undo->setText(i18n("&Undo: %1").arg(d->m_present->name()));
+ }
+
+ if(m_commands.next()!=0) {
+ if (m_redo != 0) {
+ m_redo->setEnabled(true);
+ m_redo->setText(i18n("&Redo: %1").arg(m_commands.current()->name()));
+ }
+ }
+ else {
+ if((m_redo != 0) && m_redo->isEnabled()) {
+ m_redo->setEnabled(false);
+ m_redo->setText(i18n("&Redo"));
+ }
+ }
+}
+
+void KoCommandHistory::documentSaved() {
+ if(d->m_present!=0 && !m_first)
+ d->m_savedAt=m_commands.findRef(d->m_present);
+ else if(d->m_present==0 && !m_first)
+ d->m_savedAt=-42; // this value signals that the document has
+ // been saved with an empty history.
+ else if(m_first)
+ d->m_savedAt=-42;
+}
+
+void KoCommandHistory::setUndoLimit(int limit) {
+
+ if(limit>0 && limit!=m_undoLimit) {
+ m_undoLimit=limit;
+ clipCommands();
+ }
+}
+
+void KoCommandHistory::setRedoLimit(int limit) {
+
+ if(limit>0 && limit!=m_redoLimit) {
+ m_redoLimit=limit;
+ clipCommands();
+ }
+}
+
+void KoCommandHistory::clipCommands() {
+
+ int count=m_commands.count();
+ if(count<=m_undoLimit && count<=m_redoLimit)
+ return;
+
+ int index=m_commands.findRef(d->m_present);
+ if(index>=m_undoLimit) {
+ for(int i=0; i<=(index-m_undoLimit); ++i) {
+ m_commands.removeFirst();
+ --d->m_savedAt;
+ if(d->m_savedAt==-1)
+ d->m_savedAt=-42;
+ }
+ index=m_commands.findRef(d->m_present); // calculate the new
+ count=m_commands.count(); // values (for the redo-branch :)
+ // make it easier for us... d->m_savedAt==-1 -> invalid
+ if(d->m_savedAt!=-42 && d->m_savedAt<-1)
+ d->m_savedAt=-1;
+ }
+ // adjust the index if it's the first command
+ if(m_first)
+ index=-1;
+ if((index+m_redoLimit+1)<count) {
+ if(d->m_savedAt>(index+m_redoLimit))
+ d->m_savedAt=-1;
+ for(int i=0; i<(count-(index+m_redoLimit+1)); ++i)
+ m_commands.removeLast();
+ }
+}
+
+void KoCommandHistory::slotUndoAboutToShow()
+{
+ d->m_undoListBox->clear();
+ slotChangeUndoNumberOfSelectedItem( -1 );
+ int i = 0;
+ QStringList lst;
+ if (m_commands.findRef(d->m_present)!=-1)
+ while ( m_commands.current() && i<10 ) // TODO make number of items configurable ?
+ {
+ lst.append(i18n("Undo: %1").arg(m_commands.current()->name()));
+ m_commands.prev();
+ }
+ d->m_undoListBox->insertStringList( lst );
+}
+
+void KoCommandHistory::slotUndoActivated( int pos )
+{
+ kdDebug(230) << "KoCommandHistory::slotUndoActivated " << pos << endl;
+ for ( int i = 0 ; i < pos+1; ++i )
+ undo();
+ m_undoPopup->hide();
+}
+
+void KoCommandHistory::slotUndoActivated( QListBoxItem * item)
+{
+ if ( item )
+ slotUndoActivated( item->listBox()->index(item));
+}
+
+void KoCommandHistory::slotRedoActivated( QListBoxItem * item)
+{
+ if ( item )
+ slotRedoActivated( item->listBox()->index(item));
+}
+
+void KoCommandHistory::slotChangeUndoNumberOfSelectedItem( int pos)
+{
+ d->m_undoLabel->setText( i18n("Undo %n action", "Undo %n actions", pos+1) );
+}
+
+void KoCommandHistory::slotChangeRedoNumberOfSelectedItem( int pos)
+{
+ d->m_redoLabel->setText( i18n("Redo %n action", "Redo %n actions", pos+1) );
+}
+
+
+void KoCommandHistory::slotRedoAboutToShow()
+{
+ d->m_redoListBox->clear();
+ slotChangeRedoNumberOfSelectedItem( -1 );
+ QStringList lst;
+ int i = 0;
+ if (m_first)
+ {
+ d->m_present = m_commands.first();
+ lst.append(i18n("Redo: %1").arg(d->m_present->name()));
+ }
+ if (m_commands.findRef(d->m_present)!=-1 && m_commands.next())
+ while ( m_commands.current() && i<10 ) // TODO make number of items configurable ?
+ {
+ lst.append(i18n("Redo: %1").arg(m_commands.current()->name()));
+ m_commands.next();
+ }
+ d->m_redoListBox->insertStringList( lst );
+
+}
+
+void KoCommandHistory::slotRedoActivated( int pos )
+{
+ kdDebug(230) << "KoCommandHistory::slotRedoActivated " << pos << endl;
+ for ( int i = 0 ; i < pos+1; ++i )
+ redo();
+ m_redoPopup->hide();
+}
+
+void KoCommandHistory::updateActions()
+{
+ if ( m_undo && m_redo )
+ {
+ m_undo->setEnabled( !m_first && ( d->m_present != 0L ) );
+ m_redo->setEnabled(m_first || (m_commands.findRef(d->m_present)!=-1 && m_commands.next()!=0));
+ }
+}
+
+void KoCommandHistory::virtual_hook( int, void* )
+{ /*BASE::virtual_hook( id, data );*/ }
+
+#include "KoCommandHistory.moc"
diff --git a/lib/kofficeui/KoCommandHistory.h b/lib/kofficeui/KoCommandHistory.h
new file mode 100644
index 00000000..a36ce670
--- /dev/null
+++ b/lib/kofficeui/KoCommandHistory.h
@@ -0,0 +1,198 @@
+/* This file is part of the KDE project
+ Copyright (C) 2000 Werner Trobin <trobin@kde.org>
+ Copyright (C) 2000 David Faure <faure@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#ifndef kocommandhistory_h
+#define kocommandhistory_h
+
+#include <qptrlist.h>
+#include <qstring.h>
+#include <qobject.h>
+#include <koffice_export.h>
+
+class KAction;
+class KActionCollection;
+class QPopupMenu;
+class KCommand;
+#include <qlistbox.h>
+
+class KoListBox : public QListBox {
+ Q_OBJECT
+public:
+ KoListBox( QWidget *parent = 0, const char *name = 0, WFlags f = 0 );
+protected:
+ virtual void contentsMouseMoveEvent ( QMouseEvent * );
+ virtual QSize sizeHint() const;
+signals:
+ void changeNumberOfSelectedItem( int );
+};
+
+/**
+ * The command history stores a (user) configurable amount of
+ * Commands. It keeps track of its size and deletes commands
+ * if it gets too large. The user can set a maximum undo and
+ * a maximum redo limit (e.g. max. 50 undo / 30 redo commands).
+ * The KoCommandHistory keeps track of the "borders" and deletes
+ * commands, if appropriate. It also activates/deactivates the
+ * undo/redo actions in the menu and changes the text according
+ * to the name of the command.
+ *
+ * @short History of user commands (for undo/redo)
+ */
+class KOFFICEUI_EXPORT KoCommandHistory : public QObject {
+ Q_OBJECT
+public:
+ /**
+ * Creates a command history, to store commands.
+ * This constructor doesn't create actions, so you need to call
+ * #undo and #redo yourself.
+ */
+ KoCommandHistory();
+
+ /**
+ * Creates a command history, to store commands.
+ * This also creates an undo and a redo action, in the @p actionCollection,
+ * using the standard names ("edit_undo" and "edit_redo").
+ *
+ * @param actionCollection the collection to put the history in.
+ * @param withMenus if true, the actions will display a menu when plugged
+ * into a toolbar.
+ */
+ KoCommandHistory(KActionCollection *actionCollection, bool withMenus = true);
+
+ /**
+ * Destructs the command history object.
+ */
+ virtual ~KoCommandHistory();
+
+ /**
+ * Erases all the undo/redo history.
+ * Use this when reloading the data, for instance, since this invalidates
+ * all the commands.
+ */
+ void clear();
+
+ /**
+ * Adds a command to the history. Call this for each @p command you create.
+ * Unless you set @p execute to false, this will also execute the command.
+ * This means, most of the application's code will look like:
+ *
+ * MyCommand * cmd = new MyCommand(i18n("The Name"), parameters);
+ * m_historyCommand.addCommand( cmd );
+ */
+ void addCommand(KCommand *command, bool execute=true);
+
+ /**
+ * @return the maximum number of items in the undo history
+ */
+ int undoLimit() const { return m_undoLimit; }
+ /**
+ * Sets the maximum number of items in the undo history.
+ */
+ void setUndoLimit(int limit);
+ /**
+ * @return the maximum number of items in the redo history
+ */
+ int redoLimit() const { return m_redoLimit; }
+ /**
+ * Sets the maximum number of items in the redo history.
+ */
+ void setRedoLimit(int limit);
+
+ /**
+ * Enable or disable the undo and redo actions.
+ * This isn't usually necessary, but this method can be useful if
+ * you disable all actions (to go to a "readonly" state), and then
+ * want to come back to a readwrite mode.
+ */
+ void updateActions();
+
+ /**
+ * @return the current top item on the history stack
+ */
+ KCommand * presentCommand();
+
+public slots:
+ /**
+ * Undoes the last action.
+ * Call this if you don't use the builtin KActions.
+ */
+ virtual void undo();
+ /**
+ * Redoes the last undone action.
+ * Call this if you don't use the builtin KActions.
+ */
+ virtual void redo();
+ /**
+ * Remembers when you saved the document.
+ * Call this right after saving the document. As soon as
+ * the history reaches the current index again (via some
+ * undo/redo operations) it will emit @ref documentRestored
+ * If you implemented undo/redo properly the document is
+ * the same you saved before.
+ */
+ virtual void documentSaved();
+
+protected slots:
+ void slotUndoAboutToShow();
+ void slotUndoActivated( int );
+ void slotRedoAboutToShow();
+ void slotRedoActivated( int );
+ void slotUndoActivated( QListBoxItem *);
+ void slotRedoActivated( QListBoxItem *);
+ void slotChangeRedoNumberOfSelectedItem( int );
+ void slotChangeUndoNumberOfSelectedItem( int );
+signals:
+ /**
+ * Emitted every time a command is executed
+ * (whether by addCommand, undo or redo).
+ * You can use this to update the GUI, for instance.
+ */
+ void commandExecuted();
+
+ /**
+ * Emitted every time a command is executed
+ * (whether by addCommand, undo or redo).
+ * You can use this to update the GUI, for instance.
+ * @param command was executed
+ */
+ void commandExecuted(KCommand *cmd);
+
+ /**
+ * Emitted every time we reach the index where you
+ * saved the document for the last time. See @ref #documentSaved
+ */
+ void documentRestored();
+
+private:
+ void clipCommands(); // ensures that the limits are kept
+
+ QPtrList<KCommand> m_commands;
+ KAction *m_undo, *m_redo;
+ QPopupMenu *m_undoPopup, *m_redoPopup;
+ int m_undoLimit, m_redoLimit;
+ bool m_first; // attention: it's the first command in the list!
+protected:
+ virtual void virtual_hook( int id, void* data );
+private:
+ class KoCommandHistoryPrivate;
+ KoCommandHistoryPrivate *d;
+};
+
+#endif
diff --git a/lib/kofficeui/KoContextCelp.cpp b/lib/kofficeui/KoContextCelp.cpp
new file mode 100644
index 00000000..ae28b61e
--- /dev/null
+++ b/lib/kofficeui/KoContextCelp.cpp
@@ -0,0 +1,595 @@
+/* This file is part of the KDE project
+ Copyright (C) 2002, Benoit Vautrin <benoit.vautrin@free.fr>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#include "KoContextCelp.h"
+
+#include <qpainter.h>
+#include <qregion.h>
+#include <qfont.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qsimplerichtext.h>
+
+#include <kpixmap.h>
+#include <klocale.h>
+#include <kdebug.h>
+#include <kiconloader.h>
+#include <kcursor.h>
+#include <kapplication.h>
+#include <qstring.h>
+
+KoVerticalLabel::KoVerticalLabel( QWidget* parent, const char* name )
+ : QWidget( parent, name, Qt::WRepaintNoErase )
+{
+ QFont f( font() );
+ f.setPointSize( f.pointSize() + 2 );
+ f.setBold( true );
+ setFont( f );
+ setBackgroundMode( PaletteLight );
+} // KoVerticalLabel::KoVerticalLabel
+
+KoVerticalLabel::~KoVerticalLabel()
+{
+} // KoVerticalLabel::~KoVerticalLabel
+
+void KoVerticalLabel::setText( const QString& text )
+{
+ m_text = text;
+ QFontMetrics fm( font() );
+ setMinimumSize( fm.height() + 2, fm.width( m_text ) + 4 );
+ update();
+} // KoVerticalLabel::setText
+
+void KoVerticalLabel::paintEvent( QPaintEvent* )
+{
+ KPixmap pm;
+ pm.resize( height(), width() );
+ QPainter p( &pm );
+ p.fillRect( 0, 0, height(), width(), colorGroup().background() );
+ p.setFont( font() );
+ p.drawText( 0, 0, height(), width(), AlignCenter, m_text );
+ p.end();
+ QPainter ap( this );
+ ap.rotate( 270. );
+ ap.translate( -height(), 0 );
+ ap.drawPixmap( 0, 0, pm );
+} // KoVerticalLabel::paintEvent
+
+static unsigned char upbits[] = { 0xc, 0x1e, 0x3f, 0x3f };
+static unsigned char downbits[] = { 0x3f, 0x3f, 0x1e, 0xc };
+
+KoHelpNavButton::KoHelpNavButton( NavDirection d, QWidget* parent )
+ : QWidget( parent )
+{
+ m_pressed = false;
+ m_bitmap = QBitmap( 8, 4, ( d == Up ? upbits : downbits ), true );
+ m_bitmap.setMask( m_bitmap );
+ setFixedSize( 8, 6 );
+ setBackgroundMode( PaletteLight );
+} // KoHelpNavButton::KoHelpNavButton
+
+void KoHelpNavButton::paintEvent( QPaintEvent* )
+{
+ QPainter p( this );
+ if ( isEnabled() )
+ {
+ if ( m_pressed )
+ p.setPen( colorGroup().highlight() );
+ else
+ p.setPen( colorGroup().text() );
+ p.drawPixmap( 1, 1, m_bitmap );
+ }
+} // KoHelpNavButton::paintEvent
+
+void KoHelpNavButton::enterEvent( QEvent* )
+{
+ if ( isEnabled() )
+ emit pressed();
+ m_pressed = true;
+ update();
+} // KoHelpNavButton::enterEvent
+
+void KoHelpNavButton::leaveEvent( QEvent* )
+{
+ if ( isEnabled() )
+ emit released();
+ m_pressed = false;
+ update();
+} // KoHelpNavButton::leaveEvent
+
+static unsigned char notstickybits[] = { 0x8, 0x1e, 0xc, 0xa, 0x1 };
+static unsigned char stickybits[] = { 0xe, 0x11, 0x15, 0x11, 0xe };
+static unsigned char closebits[] = { 0x11, 0xa, 0x4, 0xa, 0x11 };
+
+KoTinyButton::KoTinyButton( Action a, QWidget* parent )
+ : QWidget( parent ), m_action( a )
+{
+ m_pressed = false;
+ m_toggled = false;
+ switch ( a )
+ {
+ case Sticky:
+ m_bitmap = QBitmap( 5, 5, notstickybits, true );
+ break;
+
+ default:
+ m_bitmap = QBitmap( 5, 5, closebits, true );
+ }
+ m_bitmap.setMask( m_bitmap );
+ setMinimumSize( 7, 7 );
+ setBackgroundMode( PaletteBackground );
+} // KoTinyButton::KoTinyButton
+
+void KoTinyButton::paintEvent( QPaintEvent* )
+{
+ QPainter p( this );
+ if ( isEnabled() )
+ {
+ if ( m_pressed )
+ p.setPen( colorGroup().highlight() );
+ else
+ p.setPen( colorGroup().text() );
+ p.drawPixmap( width() / 2 - 2, 1, m_bitmap );
+ }
+} // KoTinyButton::paintEvent
+
+void KoTinyButton::mousePressEvent( QMouseEvent* )
+{
+ if ( isEnabled() )
+ {
+ m_pressed = true;
+ update();
+ }
+} // KoTinyButton::mousePressEvent
+
+void KoTinyButton::mouseReleaseEvent( QMouseEvent* )
+{
+ if ( isEnabled() && m_pressed )
+ {
+ m_pressed = false;
+ emit( clicked() );
+ if ( ( m_action == Sticky ) )
+ {
+ m_toggled = !m_toggled;
+ emit( toggled( m_toggled ) );
+ //switch ( m_action )
+ //{
+ // case Sticky:
+ m_bitmap = QBitmap( 5, 5, ( m_toggled ? stickybits : notstickybits ), true );
+ //}
+ m_bitmap.setMask( m_bitmap );
+ }
+ update();
+ }
+} // KoTinyButton::mouseReleaseEvent
+
+KoHelpView::KoHelpView( QWidget* parent )
+ : QWidget( parent )
+{
+ currentText = 0L;
+ setBackgroundMode( PaletteLight );
+ parent->installEventFilter( this );
+ setMouseTracking( true );
+} // KoHelpView::KoHelpView
+
+KoHelpView::~KoHelpView()
+{
+ if ( currentText )
+ delete currentText;
+} // KoHelpView::~KoHelpView
+
+void KoHelpView::setText( const QString& text )
+{
+ if ( currentText )
+ delete currentText;
+ currentText = new QSimpleRichText( text, font() );
+ currentText->setWidth( width() );
+ setFixedHeight( currentText->height() );
+} // KoHelpView::setText
+
+void KoHelpView::mousePressEvent( QMouseEvent* e )
+{
+ currentAnchor = currentText->anchorAt( e->pos() );
+ if ( !currentAnchor.isEmpty() )
+ e->accept();
+ else
+ e->ignore();
+} // KoHelpView::mousePressEvent
+
+void KoHelpView::mouseReleaseEvent( QMouseEvent* e )
+{
+ if ( ( !currentAnchor.isEmpty() ) && ( currentAnchor == currentText->anchorAt( e->pos() ) ) )
+ {
+ e->accept();
+ if (currentAnchor.startsWith("help://#")) {
+ //that's not really useful, since koffice documents can be embedded
+ kapp->invokeHelp(currentAnchor.right(currentAnchor.length()-8));
+ }
+ else
+ if (currentAnchor.startsWith("help://")) {
+ // that's the useful version of a help link
+ QString helpapp=currentAnchor.right(currentAnchor.length()-7);
+ QString helpanchor;
+ int pos;
+ if ((pos=helpapp.find("#"))!=-1) {
+ helpanchor=helpapp.right(helpapp.length()-pos-1);
+ helpapp=helpapp.left(pos);
+ }
+ kapp->invokeHelp(helpanchor,helpapp);
+ }
+ else
+ emit linkClicked( currentAnchor );
+ currentAnchor = "";
+ }
+ else
+ e->ignore();
+} // KoHelpView::mouseReleaseEvent
+
+void KoHelpView::mouseMoveEvent( QMouseEvent* e )
+{
+ if ( !currentText->anchorAt( e->pos() ).isEmpty() )
+ setCursor( KCursor::handCursor() );
+ else
+ setCursor( KCursor::arrowCursor() );
+} // KoHelpView::mouseMove
+
+bool KoHelpView::eventFilter( QObject*, QEvent* e )
+{
+ if ( ( currentText ) && ( e->type() == QEvent::Resize ) )
+ {
+ setFixedWidth( ( (QResizeEvent*)e )->size().width() );
+ currentText->setWidth( width() );
+ setFixedHeight( currentText->height() );
+
+ return true;
+ }
+ return false;
+} // KoHelpView::resizeEvent
+
+void KoHelpView::paintEvent( QPaintEvent* )
+{
+ QPainter p( this );
+ currentText->draw( &p, 0, 0, QRect(), colorGroup() );
+} // KoHelpView::paintEvent
+
+KoHelpWidget::KoHelpWidget( QString help, QWidget* parent )
+ : QWidget( parent )
+{
+ QGridLayout* layout = new QGridLayout( this, 3, 3 );
+ layout->setMargin( 2 );
+ layout->addWidget( m_upButton = new KoHelpNavButton( KoHelpNavButton::Up, this ), 0, 1, AlignHCenter );
+ layout->addWidget( m_helpViewport = new QWidget( this ), 1, 1 );
+ layout->addWidget( m_downButton = new KoHelpNavButton( KoHelpNavButton::Down, this ), 2, 1, AlignHCenter );
+ layout->addColSpacing( 0, 5 );
+ layout->addColSpacing( 2, 5 );
+ layout->setColStretch( 1, 1 );
+
+ m_helpView = new KoHelpView( m_helpViewport );
+ m_helpViewport->setBackgroundMode( PaletteLight );
+ setText( help );
+
+ setBackgroundMode( PaletteLight );
+
+ connect( m_upButton, SIGNAL( pressed() ), this, SLOT( startScrollingUp() ) );
+ connect( m_downButton, SIGNAL( pressed() ), this, SLOT( startScrollingDown() ) );
+ connect( m_upButton, SIGNAL( released() ), this, SLOT( stopScrolling() ) );
+ connect( m_downButton, SIGNAL( released() ), this, SLOT( stopScrolling() ) );
+ connect( m_helpView, SIGNAL( linkClicked( const QString& ) ), this, SIGNAL( linkClicked( const QString& ) ) );
+} // KoHelpWidget::KoHelpWidget
+
+void KoHelpWidget::updateButtons()
+{
+ m_upButton->setEnabled( m_ypos < 0 );
+ m_downButton->setEnabled( m_helpViewport->height() - m_ypos < m_helpView->height() );
+} // KoHelpWidget::updateButtons
+
+void KoHelpWidget::setText( QString text )
+{
+ m_helpView->setText( text );
+ m_helpView->move( 0, 0 );
+ m_ypos = 0;
+ updateButtons();
+} // KoHelpWidget::setText
+
+void KoHelpWidget::resizeEvent( QResizeEvent* )
+{
+ updateButtons();
+} // KoHelpWidget::resizeEvent
+
+void KoHelpWidget::startScrollingUp()
+{
+ if ( !m_upButton->isEnabled() )
+ return;
+ m_scrollDown = false;
+ startTimer( 80 );
+} // KoHelpWidget::startScrollingUp
+
+void KoHelpWidget::startScrollingDown()
+{
+ if ( !m_downButton->isEnabled() )
+ return;
+ m_scrollDown = true;
+ startTimer( 80 );
+} // KoHelpWidget::startScrollingDown
+
+void KoHelpWidget::scrollUp()
+{
+ if ( m_ypos > 0 )
+ stopScrolling();
+ else
+ {
+ m_ypos += 2;
+ m_helpViewport->scroll( 0, 2 );
+ m_helpViewport->update();
+ updateButtons();
+ }
+} // KoHelpWidget::scrollUp()
+
+void KoHelpWidget::scrollDown()
+{
+ if ( m_helpViewport->height() - m_helpView->height() - m_ypos > 0 )
+ stopScrolling();
+ else
+ {
+ m_ypos -= 2;
+ m_helpViewport->scroll( 0, -2 );
+ m_helpViewport->update();
+ updateButtons();
+ }
+} // KoHelpWidget::scrollUp()
+
+void KoHelpWidget::timerEvent( QTimerEvent* )
+{
+ if ( m_scrollDown )
+ scrollDown();
+ else
+ scrollUp();
+} // KoHelpWidget::timerEvent
+
+void KoHelpWidget::stopScrolling()
+{
+ killTimers();
+} // KoHelpWidget::stopScrolling
+
+KoContextHelpPopup::KoContextHelpPopup( QWidget* parent )
+ : QWidget( parent, "", WType_Dialog | WStyle_Customize | WStyle_NoBorder )
+{
+ QGridLayout* layout = new QGridLayout( this );
+ QHBoxLayout* buttonLayout;
+ layout->addWidget( m_helpIcon = new QLabel( this ), 0, 0 );
+ layout->addWidget( m_helpTitle = new KoVerticalLabel( this ), 1, 0 );
+ buttonLayout = new QHBoxLayout( layout );
+ //layout->addLayout( buttonLayout, 2, 0 );
+ layout->addMultiCellWidget( m_helpViewer = new KoHelpWidget( "", this ), 0, 2, 1, 1 );
+ buttonLayout->add( m_close = new KoTinyButton( KoTinyButton::Close, this ) );
+ buttonLayout->add( m_sticky = new KoTinyButton( KoTinyButton::Sticky, this ) );
+ layout->addColSpacing( 2, 2 );
+ layout->addRowSpacing( 3, 2 );
+ layout->setMargin( 3 );
+ layout->setSpacing( 1 );
+ layout->setRowStretch( 1, 1 );
+ buttonLayout->setSpacing( 1 );
+ setMinimumSize( 180, 180 );
+
+ m_isSticky = false;
+ setFocusPolicy( StrongFocus );
+
+ connect( m_close, SIGNAL( clicked() ), this, SIGNAL( wantsToBeClosed() ) );
+ connect( m_sticky, SIGNAL( toggled( bool ) ), this, SLOT( setSticky( bool ) ) );
+ connect( m_helpViewer, SIGNAL( linkClicked( const QString& ) ), this, SIGNAL( linkClicked( const QString& ) ) );
+} // KoContextHelpPopup::KoContextHelpPopup
+
+KoContextHelpPopup::~KoContextHelpPopup()
+{
+} // KoContextHelpPopup::~KoContextHelpPopup
+
+void KoContextHelpPopup::setContextHelp( const QString& title, const QString& text, const QPixmap* icon )
+{
+ m_helpIcon->setPixmap( icon ? *icon : BarIcon( "help" ) );
+ m_helpTitle->setText( title );
+ m_helpViewer->setText( text );
+} // KoContextHelpPopup::updateHelp
+
+void KoContextHelpPopup::mousePressEvent( QMouseEvent* e )
+{
+ m_mousePos = e->globalPos() - pos();
+} // KoContextHelpPopup::mousePressEvent
+
+void KoContextHelpPopup::mouseMoveEvent( QMouseEvent* e )
+{
+ move( e->globalPos() - m_mousePos );
+} // KoContextHelpPopup::mouseMoveEvent
+
+void KoContextHelpPopup::resizeEvent( QResizeEvent* )
+{
+ QBitmap mask( width(), height() );
+ QPointArray a;
+ QPainter p( &mask );
+ p.fillRect( 0, 0, width(), height(), color1 );
+ p.setPen( color0 );
+ p.setBrush( color0 );
+ p.drawLine( 0, 0, 0, 3 );
+ p.drawLine( 0, 0, 3, 0 );
+ p.drawPoint( 1, 1 );
+ a.setPoints( 3, 0, height() - 5, 4, height() - 1, 0, height() - 1 );
+ p.drawPolygon( a );
+ a.setPoints( 3, width() - 5, 0, width() - 1, 4, width() - 1, 0 );
+ p.drawPolygon( a );
+ p.drawLine( width() - 1, height() - 1, width() - 4, height() - 1 );
+ p.drawLine( width() - 1, height() - 1, width() - 1, height() - 4 );
+ p.drawPoint( width() - 2, height() - 2 );
+ p.drawPoint( 0, height() - 6 );
+ p.drawPoint( width() - 6, 0 );
+ p.drawPoint( width() - 5, height() - 3 );
+ p.drawPoint( width() - 3, height() - 5 );
+ p.setPen( NoPen );
+ p.setBrush( QBrush( color0, Dense4Pattern ) );
+ p.drawRect( 0, height() - 2, width() - 1, height() - 1 );
+ p.drawRect( width() - 2, 0, width() - 1, height() - 1 );
+ p.drawRect( width() - 4, height() - 4, width() - 2, height() - 2 );
+ p.end();
+ setMask( QRegion( mask ) );
+} // KoContextHelpPopup::resizeEvent
+
+void KoContextHelpPopup::paintEvent( QPaintEvent* )
+{
+ QPainter p( this );
+ p.fillRect( 0, 0, width(), height(), colorGroup().light() );
+ p.setPen( black );
+ p.drawRect( 0, 0, width(), height() );
+ p.fillRect( width() - 3, 0, width() - 1, height() - 1, black );
+ p.fillRect( 0, height() - 3, width() - 1, height() - 1, black );
+ p.drawLine( 1, 2, 1, 3 );
+ p.drawLine( 2, 1, 3, 1 );
+ p.drawLine( width() - 4, 2, width() - 4, 3 );
+ p.drawLine( width() - 5, 1, width() - 6, 1 );
+ p.drawLine( 1, height() - 5, 1, height() - 6 );
+ p.drawLine( 2, height() - 4, 3, height() - 4 );
+ p.drawLine( width() - 4, height() - 5, width() - 4, height() - 6 );
+ p.drawLine( width() - 4, height() - 4, width() - 6, height() - 4 );
+} // KoContextHelpPopup::paintEvent
+
+void KoContextHelpPopup::windowActivationChange( bool )
+{
+ if ( !isActiveWindow() && !m_isSticky )
+ emit wantsToBeClosed();
+} // KoContestHelpPopup::windowActivationChange
+
+void KoContextHelpPopup::keyPressEvent( QKeyEvent* e )
+{
+ switch ( e->key() )
+ {
+/* case Key_Up:
+ m_helpViewer->startScrollingUp();
+ break;
+
+ case Key_Down:
+ m_helpViewer->startScrollingDown();
+ break;*/
+ case Key_Up:
+ m_helpViewer->scrollUp();
+ break;
+
+ case Key_Down:
+ m_helpViewer->scrollDown();
+ break;
+ }
+} // KoContextHelpPopup::keyPressEvent
+
+void KoContextHelpPopup::keyReleaseEvent( QKeyEvent* e )
+{
+ switch ( e->key() )
+ {
+ /*case Key_Up:
+ case Key_Down:
+ m_helpViewer->stopScrolling();
+ break;*/
+
+ case Key_Escape:
+ emit wantsToBeClosed();
+ break;
+ }
+} // KoContextHelpPopup::keyPressEvent
+
+KoContextHelpAction::KoContextHelpAction( KActionCollection* parent, QWidget* /*popupParent*/ )
+ : KToggleAction( i18n( "Context Help" ), BarIcon( "help" ), KShortcut( "CTRL+SHIFT+F1" ), 0, 0, parent, "help_context" )
+{
+ m_popup = new KoContextHelpPopup( 0L );
+ connect( m_popup, SIGNAL( wantsToBeClosed() ), this, SLOT( closePopup() ) );
+ connect( this, SIGNAL( toggled( bool ) ), m_popup, SLOT( setShown( bool ) ) );
+ connect( m_popup, SIGNAL( linkClicked( const QString& ) ), this, SIGNAL( linkClicked( const QString& ) ) );
+} // KoContextHelpAction::KoContextHelpAction
+
+KoContextHelpAction::~KoContextHelpAction()
+{
+ delete m_popup;
+} // KoContextHelpAction::~KoContextHelpAction
+
+void KoContextHelpAction::updateHelp( const QString& title, const QString& text, const QPixmap* icon )
+{
+ m_popup->setContextHelp( title, text, icon );
+} // KoContextHelpAction::updateHelp
+
+void KoContextHelpAction::closePopup()
+{
+ activate();
+ setChecked( false ); // For a unknown reason, this is needed...
+} // KoContextHelpAction::closePopup
+
+
+KoContextHelpWidget::KoContextHelpWidget( QWidget* parent, const char* name )
+ : QWidget( parent, name )
+{
+ setCaption( i18n( "Context Help" ) );
+ QGridLayout* layout = new QGridLayout( this );
+ layout->addWidget( m_helpIcon = new QLabel( this ), 0, 0 );
+ layout->addWidget( m_helpTitle = new KoVerticalLabel( this ), 1, 0 );
+ layout->addMultiCellWidget( m_helpViewer = new KoHelpWidget( "", this ), 0, 1, 1, 1 );
+ layout->setMargin( 2 );
+ layout->setSpacing( 1 );
+ layout->setRowStretch( 1, 1 );
+ this->setMinimumSize( 180, 120 );
+ this->show();
+ setContextHelp( i18n( "Context Help" ), i18n( "Here will be shown help according to your actions" ), 0 );
+ connect( m_helpViewer, SIGNAL( linkClicked( const QString& ) ), this, SIGNAL( linkClicked( const QString& ) ) );
+} // KoContextHelpWidget::KoContextHelpWidget
+
+KoContextHelpWidget::~KoContextHelpWidget()
+{
+} // KoContextHelpWidget::~KoContextHelpWidget
+
+void KoContextHelpWidget::setContextHelp( const QString& title, const QString& text, const QPixmap* icon )
+{
+ m_helpIcon->setPixmap( icon ? *icon : BarIcon( "help" ) );
+ m_helpTitle->setText( title );
+ m_helpViewer->setText( text );
+} // KoContextHelpWidget::updateHelp
+
+
+KoContextHelpDocker::KoContextHelpDocker( QWidget* parent, const char* name )
+ : QDockWindow( parent, name )
+{
+ setCaption( i18n( "Context Help" ) );
+ QWidget* mainWidget = new QWidget( this );
+ QGridLayout* layout = new QGridLayout( mainWidget );
+ layout->addWidget( m_helpIcon = new QLabel( mainWidget ), 0, 0 );
+ layout->addWidget( m_helpTitle = new KoVerticalLabel( mainWidget ), 1, 0 );
+ layout->addMultiCellWidget( m_helpViewer = new KoHelpWidget( "", mainWidget ), 0, 1, 1, 1 );
+ layout->setMargin( 2 );
+ layout->setSpacing( 1 );
+ layout->setRowStretch( 1, 1 );
+ mainWidget->setMinimumSize( 180, 120 );
+ mainWidget->show();
+ setWidget( mainWidget );
+ setContextHelp( i18n( "Context Help" ), i18n( "Here will be shown help according to your actions" ), 0 );
+ connect( m_helpViewer, SIGNAL( linkClicked( const QString& ) ), this, SIGNAL( linkClicked( const QString& ) ) );
+} // KoContextHelpDocker::KoContextHelpDocker
+
+KoContextHelpDocker::~KoContextHelpDocker()
+{
+} // KoContextHelpDocker::~KoContextHelpDocker
+
+void KoContextHelpDocker::setContextHelp( const QString& title, const QString& text, const QPixmap* icon )
+{
+ m_helpIcon->setPixmap( icon ? *icon : BarIcon( "help" ) );
+ m_helpTitle->setText( title );
+ m_helpViewer->setText( text );
+} // KoContextHelpDocker::updateHelp
+
+#include "KoContextCelp.moc"
diff --git a/lib/kofficeui/KoContextCelp.h b/lib/kofficeui/KoContextCelp.h
new file mode 100644
index 00000000..07f80d8f
--- /dev/null
+++ b/lib/kofficeui/KoContextCelp.h
@@ -0,0 +1,279 @@
+/* This file is part of the KDE project
+ Copyright (C) 2002, Benoit Vautrin <benoit.vautrin@free.fr>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#ifndef __KOCONTEXTHELPACTION_H__
+#define __KOCONTEXTHELPACTION_H__
+
+#include <qwidget.h>
+#include <qbitmap.h>
+#include <qdockwindow.h>
+
+#include <kaction.h>
+#include <koffice_export.h>
+class QPixmap;
+class QLabel;
+class QSimpleRichText;
+
+class KoVerticalLabel : public QWidget
+{
+ Q_OBJECT
+
+ public:
+ KoVerticalLabel( QWidget* parent = 0, const char* name = 0 );
+ ~KoVerticalLabel();
+
+ public slots:
+ void setText( const QString& text );
+
+ protected:
+ void paintEvent( QPaintEvent* );
+
+ private:
+ QString m_text;
+}; // KoVerticalLabel
+
+class KoHelpNavButton : public QWidget
+{
+ Q_OBJECT
+
+ public:
+ enum NavDirection {
+ Up,
+ Down
+ };
+
+ KoHelpNavButton( NavDirection d, QWidget* parent );
+
+ signals:
+ void pressed();
+ void released();
+
+ protected:
+ void paintEvent( QPaintEvent* );
+ void enterEvent( QEvent* );
+ void leaveEvent( QEvent* );
+
+ private:
+ QBitmap m_bitmap;
+ bool m_pressed;
+}; // KoHelpNavButton
+
+class KoTinyButton : public QWidget
+{
+ Q_OBJECT
+
+ public:
+ enum Action {
+ Close,
+ Sticky
+ };
+
+ KoTinyButton( Action a, QWidget* parent );
+
+ signals:
+ void clicked();
+ void toggled( bool );
+
+ protected:
+ void paintEvent( QPaintEvent* );
+ void mousePressEvent( QMouseEvent* );
+ void mouseReleaseEvent( QMouseEvent* );
+
+ private:
+ QBitmap m_bitmap;
+ bool m_pressed;
+ Action m_action;
+ bool m_toggled;
+}; // KoTinyButton
+
+class KoHelpView : public QWidget
+{
+ Q_OBJECT
+
+ public:
+ KoHelpView( QWidget* parent );
+ ~KoHelpView();
+
+ void setText( const QString& text );
+ bool eventFilter( QObject* watched, QEvent* e );
+
+ signals:
+ void linkClicked( const QString& link );
+
+ protected:
+ virtual void mousePressEvent( QMouseEvent* e );
+ virtual void mouseReleaseEvent( QMouseEvent* e );
+ virtual void mouseMoveEvent( QMouseEvent* e );
+ virtual void paintEvent( QPaintEvent* e );
+
+ private:
+ QSimpleRichText* currentText;
+ QString currentAnchor;
+}; // KoHelpView
+
+class KoHelpWidget : public QWidget
+{
+ Q_OBJECT
+
+ public:
+ KoHelpWidget( QString help, QWidget* parent );
+
+ void setText( QString text );
+ void timerEvent( QTimerEvent* );
+ void updateButtons();
+
+ signals:
+ void linkClicked( const QString& link );
+
+ public slots:
+ void scrollUp();
+ void scrollDown();
+ void startScrollingUp();
+ void startScrollingDown();
+ void stopScrolling();
+
+ protected:
+ void resizeEvent( QResizeEvent* );
+
+ private:
+ int m_ypos;
+ bool m_scrollDown;
+ QWidget* m_helpViewport;
+ KoHelpView* m_helpView;
+ KoHelpNavButton* m_upButton;
+ KoHelpNavButton* m_downButton;
+}; // KoHelpWidget
+
+/**
+ * KoContextHelpPopup is the popup displayed by ContextHelpAction.
+ */
+class KoContextHelpPopup : public QWidget
+{
+ Q_OBJECT
+
+ public:
+ KoContextHelpPopup( QWidget* parent = 0 );
+ ~KoContextHelpPopup();
+
+ public slots:
+ void setContextHelp( const QString& title, const QString& text, const QPixmap* icon = 0 );
+ void setSticky( bool sticky ) { m_isSticky = sticky; }
+
+ protected:
+ virtual void mousePressEvent( QMouseEvent* );
+ virtual void mouseMoveEvent( QMouseEvent* );
+ virtual void resizeEvent( QResizeEvent* );
+ virtual void paintEvent( QPaintEvent* );
+ virtual void windowActivationChange( bool );
+ virtual void keyPressEvent ( QKeyEvent* );
+ virtual void keyReleaseEvent ( QKeyEvent* );
+
+ signals:
+ void wantsToBeClosed();
+ /**
+ * Connect to this signal to receive the href value of the links clicked.
+ */
+ void linkClicked( const QString& link );
+
+ private:
+ KoHelpWidget* m_helpViewer;
+ KoVerticalLabel* m_helpTitle;
+ QLabel* m_helpIcon;
+ KoTinyButton* m_close;
+ KoTinyButton* m_sticky;
+
+ QPoint m_mousePos;
+ bool m_isSticky;
+}; // KoContextHelpPopup
+
+/**
+ * KoContextHelpAction provides a easy to use context help system.
+ *
+ * This action displays on demand a context help in a popup.
+ * The context help is set by the updateHelp slot.
+ */
+class KOFFICEUI_EXPORT KoContextHelpAction : public KToggleAction
+{
+ Q_OBJECT
+
+ public:
+ KoContextHelpAction( KActionCollection* parentCollection, QWidget* parent = 0 );
+ virtual ~KoContextHelpAction();
+
+ public slots:
+ void updateHelp( const QString& title, const QString& text, const QPixmap* icon = 0 );
+ void closePopup();
+
+ signals:
+ /**
+ * Connect to this signal to receive the href value of the links clicked.
+ */
+ void linkClicked( const QString& link );
+
+ private:
+ KoContextHelpPopup* m_popup;
+}; // KoContextHelpAction
+
+class KoContextHelpWidget : public QWidget
+{
+ Q_OBJECT
+
+ public:
+ KoContextHelpWidget( QWidget* parent = 0, const char* name = 0 );
+ ~KoContextHelpWidget();
+
+ public slots:
+ void setContextHelp( const QString& title, const QString& text, const QPixmap* icon = 0 );
+
+ signals:
+ /**
+ * Connect to this signal to receive the href value of the links clicked.
+ */
+ void linkClicked( const QString& link );
+
+ private:
+ KoHelpWidget* m_helpViewer;
+ KoVerticalLabel* m_helpTitle;
+ QLabel* m_helpIcon;
+}; // KoContextHelpWidget
+
+class KoContextHelpDocker : public QDockWindow
+{
+ Q_OBJECT
+
+ public:
+ KoContextHelpDocker( QWidget* parent = 0, const char* name = 0 );
+ ~KoContextHelpDocker();
+
+ public slots:
+ void setContextHelp( const QString& title, const QString& text, const QPixmap* icon = 0 );
+
+ signals:
+ /**
+ * Connect to this signal to receive the href value of the links clicked.
+ */
+ void linkClicked( const QString& link );
+
+ private:
+ KoHelpWidget* m_helpViewer;
+ KoVerticalLabel* m_helpTitle;
+ QLabel* m_helpIcon;
+}; // KoContextHelpDocker
+
+#endif /* __KOCONTEXTHELPACTION_H__ */
diff --git a/lib/kofficeui/KoEditPath.cpp b/lib/kofficeui/KoEditPath.cpp
new file mode 100644
index 00000000..8f7aa19e
--- /dev/null
+++ b/lib/kofficeui/KoEditPath.cpp
@@ -0,0 +1,98 @@
+/* This file is part of the KDE project
+ Copyright (C) 2002 Montel Laurent <lmontel@mandrakesoft.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#include <kdeversion.h>
+#include <klocale.h>
+#include <qlayout.h>
+#include <qpushbutton.h>
+#include <qlistbox.h>
+#include "KoEditPath.h"
+#include <keditlistbox.h>
+#include <kfiledialog.h>
+#include <kurlrequester.h>
+#include <qhbox.h>
+#include <klineedit.h>
+#include <qvbox.h>
+#include <qcheckbox.h>
+#include <qlabel.h>
+
+KoEditPathDia::KoEditPathDia( const QString & _path, QWidget *parent, const char *name )
+ : KDialogBase( parent, name , true, "", Ok|Cancel, Ok, true )
+{
+ setCaption( i18n("Edit Path") );
+ QWidget *page = new QWidget( this );
+ setMainWidget(page);
+ QGridLayout * grid = new QGridLayout(page, 5, 2, KDialog::marginHint(), KDialog::spacingHint());
+
+ urlReq = new KURLRequester();
+ urlReq->fileDialog()->setMode(KFile::Directory | KFile::LocalOnly);
+
+ KEditListBox::CustomEditor tmp(urlReq, urlReq->lineEdit());
+
+ m_listpath = new KEditListBox( i18n("Expression Path"),
+ tmp,page, "list_editor" , false, KEditListBox::Add|KEditListBox::Remove );
+
+ grid->addMultiCellWidget(m_listpath, 0, 4, 0, 0);
+ m_listpath->listBox()->insertStringList(QStringList::split(QString(";"), _path));
+ setFocus();
+ resize( 500, 300);
+}
+
+QString KoEditPathDia::newPath()const
+{
+ QString tmp;
+ for (int i = 0; i <(int)m_listpath->listBox()->count(); i++)
+ {
+ if ( i!=0)
+ tmp +=";";
+ tmp += m_listpath->listBox()->text( i );
+ }
+ return tmp;
+}
+
+
+KoChangePathDia::KoChangePathDia( const QString & _path, QWidget *parent, const char *name )
+ : KDialogBase( parent, name , true, "", Ok|Cancel, Ok, true )
+{
+ setCaption( i18n("Edit Path") );
+
+ QVBox *page =makeVBoxMainWidget();
+ new QLabel( i18n("Location:"), page);
+ m_urlReq = new KURLRequester(page);
+ m_urlReq->setMinimumWidth( m_urlReq->sizeHint().width() * 3 );
+
+ m_urlReq->lineEdit()->setText( _path );
+ m_urlReq->fileDialog()->setMode(KFile::Directory | KFile::LocalOnly);
+ m_defaultPath = new QCheckBox( i18n("Default path"), page );
+ connect( m_defaultPath, SIGNAL(toggled ( bool )), this, SLOT( slotChangeDefaultValue( bool )));
+ slotChangeDefaultValue( _path.isEmpty() );
+ m_defaultPath->setChecked( _path.isEmpty() );
+}
+
+QString KoChangePathDia::newPath() const
+{
+ return m_defaultPath->isChecked() ? QString::null : m_urlReq->lineEdit()->text();
+}
+
+void KoChangePathDia::slotChangeDefaultValue( bool _b)
+{
+ m_urlReq->setEnabled( !_b);
+}
+
+#include "KoEditPath.moc"
diff --git a/lib/kofficeui/KoEditPath.h b/lib/kofficeui/KoEditPath.h
new file mode 100644
index 00000000..6ec99333
--- /dev/null
+++ b/lib/kofficeui/KoEditPath.h
@@ -0,0 +1,55 @@
+/* This file is part of the KDE project
+ Copyright (C) 2002 Montel Laurent <lmontel@mandrakesoft.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#ifndef __KOEditPathDia__
+#define __KOEditPathDia__
+
+#include <kdialogbase.h>
+#include <qstringlist.h>
+#include <koffice_export.h>
+class KEditListBox;
+class KURLRequester;
+class QCheckBox;
+
+class KOFFICEUI_EXPORT KoEditPathDia : public KDialogBase
+{
+ Q_OBJECT
+public:
+ KoEditPathDia( const QString & _path, QWidget *parent, const char *name );
+ QString newPath()const;
+
+private:
+ KEditListBox *m_listpath;
+ KURLRequester *urlReq;
+};
+
+class KOFFICEUI_EXPORT KoChangePathDia : public KDialogBase
+{
+ Q_OBJECT
+public:
+ KoChangePathDia( const QString & _path, QWidget *parent, const char *name );
+ QString newPath()const;
+private slots:
+ void slotChangeDefaultValue( bool );
+private:
+ KURLRequester *m_urlReq;
+ QCheckBox *m_defaultPath;
+};
+
+#endif
diff --git a/lib/kofficeui/KoGeneralPropertyUi.ui b/lib/kofficeui/KoGeneralPropertyUi.ui
new file mode 100644
index 00000000..41d4bb98
--- /dev/null
+++ b/lib/kofficeui/KoGeneralPropertyUi.ui
@@ -0,0 +1,193 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>KoGeneralPropertyUI</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>KoGeneralPropertyUI</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>292</width>
+ <height>222</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>General</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLayoutWidget" row="0" column="0">
+ <property name="name">
+ <cstring>layout13</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>nameLabel</cstring>
+ </property>
+ <property name="text">
+ <string>Na&amp;me:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>nameInput</cstring>
+ </property>
+ </widget>
+ <widget class="QLineEdit">
+ <property name="name">
+ <cstring>nameInput</cstring>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QCheckBox" row="1" column="0">
+ <property name="name">
+ <cstring>protect</cstring>
+ </property>
+ <property name="text">
+ <string>Protect si&amp;ze and position</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="2" column="0">
+ <property name="name">
+ <cstring>keepRatio</cstring>
+ </property>
+ <property name="text">
+ <string>Keep &amp;aspect ratio</string>
+ </property>
+ </widget>
+ <widget class="QGroupBox" row="3" column="0">
+ <property name="name">
+ <cstring>positionGroup</cstring>
+ </property>
+ <property name="title">
+ <string>Position</string>
+ </property>
+ <property name="flat">
+ <bool>false</bool>
+ </property>
+ <property name="checkable">
+ <bool>false</bool>
+ </property>
+ <property name="checked">
+ <bool>false</bool>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>widthLabel</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Width:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>widthInput</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="2">
+ <property name="name">
+ <cstring>heightLabel</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Height:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>heightInput</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="2">
+ <property name="name">
+ <cstring>topLabel</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Top:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>yInput</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>leftLabel</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Left:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>xInput</cstring>
+ </property>
+ </widget>
+ <widget class="KoUnitDoubleSpinBox" row="0" column="1">
+ <property name="name">
+ <cstring>xInput</cstring>
+ </property>
+ </widget>
+ <widget class="KoUnitDoubleSpinBox" row="0" column="3">
+ <property name="name">
+ <cstring>yInput</cstring>
+ </property>
+ </widget>
+ <widget class="KoUnitDoubleSpinBox" row="1" column="3">
+ <property name="name">
+ <cstring>heightInput</cstring>
+ </property>
+ </widget>
+ <widget class="KoUnitDoubleSpinBox" row="1" column="1">
+ <property name="name">
+ <cstring>widthInput</cstring>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <spacer row="4" column="0">
+ <property name="name">
+ <cstring>spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>21</height>
+ </size>
+ </property>
+ </spacer>
+ </grid>
+</widget>
+<customwidgets>
+ <customwidget>
+ <class>KoUnitDoubleSpinBox</class>
+ <header location="local">KoUnitWidgets.h</header>>
+ <sizehint>
+ <width>-1</width>
+ <height>-1</height>
+ </sizehint>
+ <container>0</container>
+ <sizepolicy>
+ <hordata>5</hordata>
+ <verdata>5</verdata>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ <pixmap>image0</pixmap>
+ </customwidget>
+</customwidgets>
+<images>
+ <image name="image0">
+ <data format="PNG" length="1008">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b000003b749444154388db59541681d551486bf49aef55c4965061b98815a5e20a5790b912c0d66d12c0381361004219bae0a45041111a92d28086a4110eaa68a8bd8b8a97121348b96b810cca6988281111a9c27446720afcc8516efa94e3b2e665e6244832e3c70b8cce5f2cf77cffc734e50d735830882600818060c3004046d1e14759b8f800a7858d7f5a360207cfe8df34f7627ba679d7367f27e7ea27425168bc71fb896ae24bd936eaddf5a5fa6e213e02ef0c00c48af5dbd76364a7837390e9d4a5b98128c0025d608e0f7f6d97b4eefc8389f8617d66f3a0b7c0894a63d395cf48b33d1d390f5bf40ef65f84ab116fcefe00a212f1441b04760ec38882854a0801c866854015e00aeee1203a6ec97273c0ebd57e02b873d1c926dc0daaab271ab400c68a5880989c785d98588a9698fd0ec872302e83120fa33f150ee7226517c95636dc8b73794e52b0e2a08432119174420ef29bd2de5a3b7338ac598f9451069c4dbb0c0a18170608d05147b58c83660a5159d3d1573720e92c482f1a846acad7a56ae3856967ac4719799d316314a53188681606820ec2b0f08dec3f5af1c5a29b3a762e6cf4094286a72dc8ee5fa9725b30b112fbe148211969772b4bfcf7e01100c88b1c682297145447a3b230c1b5291e68aee7ec2e5f74bb24d47b903e75e4b58bfe1c87e50d2d423b2dfdc03627ce5b146c88b120c241d884641519c8bb8fc564ebae99050989a8e60a4a43b19a295926f8356ff20dcd41804814a0947da8fb29370f99d926cb3b157382224472112c08018412b90bf20ef2306b047001392f61455cbda4ddf908e08f1d1905eafe0d2c59c742322cf14ad94b18e853d5734fedd4f5cd23d0e9d8e50f494b555cffc6244b9a34c9d8c4862b874117a5b05e75fced1fb8e380ee94e425e1c50631010657641d04a59b9e2585b2d39f74ac2e4b4a733e979f5cd84380e71fd022a989a0b199bd8e7e3bf23f6500953d3506cc7ac2cf558fe00d66f38bacf846020cf4a5c5f9bdaa2a4df28e96d4b2842ebe37dc275d92fdb7f5f11607e5188e32e2b9fe7a49b4a7abbd79cae203c1232733ae4bbaf95fcbe43ab88a2bf2b5a03f5ae707a27dd4a331997a821110333739ea9e98434f5e4db8d68d2b17427616c02d2390b5502a624fb1e805f8087401dd4754d100416c3ebcf3d2f17a2a4b194aa3270bdb4af17d37633da9b19c139483794bc505cc155e063e047da46ff18700c780ff889bda9f06ff367e033e034f02c303a201ea2e94a11f054bb5ada86c2c151b7d7f73413e02e50ee8ea620080cf038f0442b7a88ff36f37e6bc57f051e04ffd730fd03ef8bd61b5b2ca6900000000049454e44ae426082</data>
+ </image>
+</images>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/lib/kofficeui/KoGuideLineDia.cpp b/lib/kofficeui/KoGuideLineDia.cpp
new file mode 100644
index 00000000..db58ed28
--- /dev/null
+++ b/lib/kofficeui/KoGuideLineDia.cpp
@@ -0,0 +1,131 @@
+// -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4; -*-
+/* This file is part of the KDE project
+ Copyright (C) 2002 Montel Laurent <lmontel@mandrakesoft.com>
+ Copyright (C) 2005 Thorsten Zachmann <zachmann@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#include "KoGuideLineDia.h"
+
+#include <qbuttongroup.h>
+#include <qhbox.h>
+#include <qvbox.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qradiobutton.h>
+
+#include <klocale.h>
+#include <KoUnitWidgets.h>
+
+
+KoGuideLineDia::KoGuideLineDia( QWidget *parent, double pos, double minPos, double maxPos,
+ KoUnit::Unit unit, const char *name )
+: KDialogBase( parent, name , true, "", Ok | Cancel, Ok, true )
+, m_hButton( 0 )
+, m_vButton( 0 )
+{
+ setCaption( i18n("Set Guide Line Position") );
+ QHBox *page = makeHBoxMainWidget();
+ new QLabel( i18n( "Position:" ), page );
+ m_position= new KoUnitDoubleSpinBox( page, QMAX( 0.00, minPos ), QMAX( 0.00, maxPos ), 1, QMAX( 0.00, pos ), unit );
+ m_position->setFocus();
+}
+
+
+KoGuideLineDia::KoGuideLineDia( QWidget *parent, KoPoint &pos, KoRect &rect,
+ KoUnit::Unit unit, const char *name )
+: KDialogBase( parent, name , true, "", Ok | Cancel, Ok, true )
+, m_rect( rect )
+, m_pos( pos )
+, m_positionChanged( false )
+, m_hButton( 0 )
+, m_vButton( 0 )
+{
+ setCaption( i18n("Add Guide Line") );
+ QVBox * vbox = makeVBoxMainWidget();
+
+ QButtonGroup *group = new QButtonGroup( 1, QGroupBox::Horizontal, i18n( "Orientation" ), vbox );
+ group->setRadioButtonExclusive( true );
+ //group->layout();
+ m_hButton = new QRadioButton( i18n( "Horizontal" ), group );
+ m_vButton = new QRadioButton( i18n( "Vertical" ), group );
+
+ connect( group, SIGNAL( clicked( int ) ), this, SLOT( slotOrientationChanged() ) );
+
+ m_vButton->setChecked( true );;
+
+ QHBox *hbox = new QHBox( vbox );
+ QLabel *label = new QLabel( i18n( "&Position:" ), hbox );
+ m_position= new KoUnitDoubleSpinBox( hbox, QMAX( 0.0, m_rect.left() ), QMAX( 0.0, m_rect.right() ), 1, QMAX( 0.0, pos.x() ), unit );
+ m_position->setFocus();
+ label->setBuddy( m_position );
+
+ connect( m_position, SIGNAL( valueChanged( double ) ), this, SLOT( slotPositionChanged() ) );
+}
+
+
+double KoGuideLineDia::pos() const
+{
+ return m_position->value();
+}
+
+
+Qt::Orientation KoGuideLineDia::orientation() const
+{
+ Qt::Orientation o = Qt::Horizontal;
+ if ( m_vButton && m_vButton->isChecked() )
+ {
+ o = Qt::Vertical;
+ }
+ return o;
+}
+
+
+void KoGuideLineDia::slotOrientationChanged()
+{
+ if ( m_hButton && m_vButton )
+ {
+ if ( m_hButton->isChecked() )
+ {
+ m_position->setMinValue( QMAX( 0.0, m_rect.top() ) );
+ m_position->setMaxValue( QMAX( 0.0, m_rect.bottom() ) );
+ if ( ! m_positionChanged )
+ {
+ disconnect( m_position, SIGNAL( valueChanged( double ) ), this, SLOT( slotPositionChanged() ) );
+ m_position->changeValue( m_pos.y() );
+ connect( m_position, SIGNAL( valueChanged( double ) ), this, SLOT( slotPositionChanged() ) );
+ }
+ }
+ else if ( m_vButton->isChecked() )
+ {
+ m_position->setMinValue( QMAX( 0.0, m_rect.left() ) );
+ m_position->setMaxValue( QMAX( 0.0, m_rect.right() ) );
+ if ( ! m_positionChanged )
+ {
+ disconnect( m_position, SIGNAL( valueChanged( double ) ), this, SLOT( slotPositionChanged() ) );
+ m_position->changeValue( m_pos.x() );
+ connect( m_position, SIGNAL( valueChanged( double ) ), this, SLOT( slotPositionChanged() ) );
+ }
+ }
+ }
+}
+
+void KoGuideLineDia::slotPositionChanged()
+{
+ m_positionChanged = true;
+}
+#include "KoGuideLineDia.moc"
diff --git a/lib/kofficeui/KoGuideLineDia.h b/lib/kofficeui/KoGuideLineDia.h
new file mode 100644
index 00000000..8545f35d
--- /dev/null
+++ b/lib/kofficeui/KoGuideLineDia.h
@@ -0,0 +1,96 @@
+// -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4; -*-
+/* This file is part of the KDE project
+ Copyright (C) 2002 Montel Laurent <lmontel@mandrakesoft.com>
+ Copyright (C) 2005 Thorsten Zachmann <zachmann@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KOGUIDELINEDIA_H
+#define KOGUIDELINEDIA_H
+
+#include <kdialogbase.h>
+#include <KoUnit.h>
+#include "KoRect.h"
+#include "KoPoint.h"
+
+
+class KoUnitDoubleSpinBox;
+class QRadioButton;
+
+/**
+ * @brief Class for setting a guide line position.
+ */
+class KoGuideLineDia : public KDialogBase
+{
+ Q_OBJECT
+public:
+ /**
+ * @brief Constructor
+ *
+ * @param parent The parent widget
+ * @param pos the actual position of the guide line
+ * @param minPos the minimal position of the guide line
+ * @param maxPos the maximal position of the guide line
+ * @param unit The unit used in the document
+ * @param name The name is send to the QObject constructor
+ */
+ KoGuideLineDia( QWidget *parent, double pos, double minPos, double maxPos,
+ KoUnit::Unit unit, const char *name = 0L );
+
+ /**
+ * @brief Constructor
+ *
+ * This shows a dialog to add a guide line. As long the position is not changed
+ * and the orientation of the guide line is changed the value will be set to pos.x()
+ * or pos.y() according to the orientation.
+ *
+ * @param parent the parent widget
+ * @param pos the actual position of cursor
+ * @param rect the rect in where the guide can be placed
+ * @param unit the unit used in the document
+ * @param name the name is send to the QObject constructor
+ */
+ KoGuideLineDia( QWidget *parent, KoPoint &pos, KoRect &rect,
+ KoUnit::Unit unit, const char *name = 0L );
+ /**
+ * @brief the position
+ *
+ * @return the value of the position input
+ */
+ double pos() const;
+
+ /**
+ * @brief the orientation
+ *
+ * @return the orientation of the added guide line
+ */
+ Qt::Orientation orientation() const;
+
+protected slots:
+ void slotOrientationChanged();
+ void slotPositionChanged();
+
+protected:
+ KoRect m_rect;
+ KoPoint m_pos;
+ bool m_positionChanged;
+ QRadioButton * m_hButton;
+ QRadioButton * m_vButton;
+ KoUnitDoubleSpinBox* m_position;
+};
+
+#endif // KOGUIDELINEDIA_H
diff --git a/lib/kofficeui/KoGuides.cpp b/lib/kofficeui/KoGuides.cpp
new file mode 100644
index 00000000..f6d375f6
--- /dev/null
+++ b/lib/kofficeui/KoGuides.cpp
@@ -0,0 +1,926 @@
+// -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4; -*-
+/* This file is part of the KDE project
+ Copyright (C) 2005 Thorsten Zachmann <zachmann@kde.org>
+ Copyright (C) 2005 Casper Boemann Rasmussen <cbr@boemann.dk>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "KoGuides.h"
+
+#include <qcursor.h>
+#include <qpainter.h>
+#include <qpixmap.h>
+
+#include <klocale.h>
+#include <kpopupmenu.h>
+
+#include <KoDocument.h>
+#include <KoPoint.h>
+#include <KoRect.h>
+#include <KoView.h>
+#include <KoZoomHandler.h>
+
+#include "KoGuideLineDia.h"
+
+class KoGuides::Popup : public KPopupMenu
+{
+public:
+ Popup( KoGuides * guides )
+ {
+ m_title = insertTitle( i18n( "Guide Line" ) );
+ m_delete = insertItem( i18n( "&Delete" ), guides, SLOT( slotRemove() ) );
+ m_seperator = insertSeparator();
+ m_pos = insertItem( i18n( "&Set Position..." ), guides, SLOT( slotChangePosition() ) );
+ }
+
+ void update( int count )
+ {
+ if ( count == 1 )
+ {
+ changeTitle( m_title, i18n( "Guide Line" ) );
+ setItemVisible( m_seperator, true );
+ setItemVisible( m_pos, true );
+ }
+ else
+ {
+ changeTitle( m_title, i18n( "Guide Lines" ) );
+ setItemVisible( m_seperator, false );
+ setItemVisible( m_pos, false );
+ }
+ }
+private:
+ int m_title;
+ int m_delete;
+ int m_seperator;
+ int m_pos;
+};
+
+const KoGuides::SnapStatus KoGuides::SNAP_NONE = 0;
+const KoGuides::SnapStatus KoGuides::SNAP_HORIZ = 1;
+const KoGuides::SnapStatus KoGuides::SNAP_VERT = 2;
+const KoGuides::SnapStatus KoGuides::SNAP_BOTH = 3;
+
+KoGuides::KoGuides( KoView *view, KoZoomHandler *zoomHandler )
+: m_view( view )
+, m_zoomHandler( zoomHandler )
+{
+ m_popup = new Popup( this );
+ m_mouseSelected = false;
+}
+
+
+KoGuides::~KoGuides()
+{
+ delete m_popup;
+}
+
+
+void KoGuides::paintGuides( QPainter &painter )
+{
+ //painter.setRasterOp( NotROP );
+ const KoPageLayout& pl = m_view->koDocument()->pageLayout();
+ int width = QMAX( m_view->canvas()->width(), m_zoomHandler->zoomItX( pl.ptWidth ) );
+ int height = QMAX( m_view->canvas()->height(), m_zoomHandler->zoomItY( pl.ptHeight ) );
+
+ for ( int i = 0; i < GL_END; ++i )
+ {
+ QValueList<KoGuideLine *>::iterator it = m_guideLines[i].begin();
+ for ( ; it != m_guideLines[i].end(); ++it )
+ {
+ if ( !( *it )->automatic || ( *it )->snapping ) // dont paint autoStyle guides when they are not snapping
+ {
+ if ( ( *it )->snapping )
+ painter.setPen( QPen( green, 0, DotLine ) );
+ else if ( ( *it )->selected )
+ painter.setPen( QPen( red, 0, DotLine ) );
+ else
+ painter.setPen( QPen( blue, 0, DotLine ) );
+
+ painter.save();
+ if ( ( *it )->orientation == Qt::Vertical )
+ {
+ painter.translate( m_zoomHandler->zoomItX( ( *it )->position ), 0 );
+ painter.drawLine( 0, 0, 0, height );
+ }
+ else
+ {
+ painter.translate( 0, m_zoomHandler->zoomItY( ( *it )->position ) );
+ painter.drawLine( 0, 0, width, 0 );
+ }
+ painter.restore();
+ }
+ }
+ }
+}
+
+bool KoGuides::mousePressEvent( QMouseEvent *e )
+{
+ bool eventProcessed = true;
+ bool changed = false;
+ m_mouseSelected = false;
+
+ KoPoint p( mapFromScreen( e->pos() ) );
+ KoGuideLine * guideLine = find( p, m_zoomHandler->unzoomItY( 2 ) );
+ if ( guideLine )
+ {
+ m_lastPoint = e->pos();
+ if ( e->button() == Qt::LeftButton || e->button() == Qt::RightButton )
+ {
+ if ( e->button() == Qt::LeftButton )
+ {
+ m_mouseSelected = true;
+ }
+ if ( e->state() & Qt::ControlButton )
+ {
+ if ( guideLine->selected )
+ {
+ unselect( guideLine );
+ m_mouseSelected = false;
+ }
+ else
+ {
+ select( guideLine );
+ }
+ changed = true;
+ }
+ else if ( ! guideLine->selected )
+ {
+ unselectAll();
+ select( guideLine );
+ changed = true;
+ }
+ }
+ }
+ else
+ {
+ if ( !( e->state() & Qt::ControlButton ) )
+ {
+ changed = unselectAll();
+ }
+ eventProcessed = false;
+ }
+
+ if ( changed || hasSelected() )
+ {
+ emit moveGuides( true );
+ }
+
+ if ( changed )
+ {
+ paint();
+ }
+
+ if ( changed && ! hasSelected() )
+ {
+ emit moveGuides( false );
+ }
+
+ if ( e->button() == Qt::RightButton && hasSelected() )
+ {
+ m_popup->update( m_guideLines[GL_SELECTED].count() );
+ m_popup->exec( QCursor::pos() );
+ emit moveGuides( false );
+ }
+
+ return eventProcessed;
+}
+
+
+bool KoGuides::mouseMoveEvent( QMouseEvent *e )
+{
+ bool eventProcessed = false;
+ if ( m_mouseSelected )
+ {
+ QPoint p( e->pos() );
+ p -= m_lastPoint;
+ m_lastPoint = e->pos();
+ moveSelectedBy( p );
+ paint();
+ emit guideLinesChanged( m_view );
+ eventProcessed = true;
+ }
+ else if ( e->state() == Qt::NoButton )
+ {
+ KoPoint p( mapFromScreen( e->pos() ) );
+ KoGuideLine * guideLine = find( p, m_zoomHandler->unzoomItY( 2 ) );
+ if ( guideLine )
+ {
+ m_view->canvas()->setCursor( guideLine->orientation == Qt::Vertical ? Qt::sizeHorCursor : Qt::sizeVerCursor );
+ eventProcessed = true;
+ }
+ }
+ return eventProcessed;
+}
+
+
+bool KoGuides::mouseReleaseEvent( QMouseEvent *e )
+{
+ bool eventProcessed = false;
+ if ( m_mouseSelected )
+ {
+ KoPoint p( mapFromScreen( e->pos() ) );
+ if ( m_guideLines[GL_SELECTED].count() == 1 )
+ {
+ int x1, y1, x2, y2;
+ m_view->canvas()->rect().coords( &x1, &y1, &x2, &y2 );
+ QPoint gp( m_view->canvas()->mapFromGlobal( e->globalPos() ) );
+ if ( m_guideLines[GL_SELECTED].first()->orientation == Qt::Vertical )
+ {
+ if ( gp.x() < x1 || gp.x() > x2 )
+ removeSelected();
+ }
+ else
+ {
+ if ( gp.y() < y1 || gp.y() > y2 )
+ removeSelected();
+ }
+ }
+ KoGuideLine * guideLine = find( p, m_zoomHandler->unzoomItY( 2 ) );
+ if ( guideLine )
+ {
+ m_view->canvas()->setCursor( guideLine->orientation == Qt::Vertical ? Qt::sizeHorCursor : Qt::sizeVerCursor );
+ }
+ m_mouseSelected = false;
+ eventProcessed = true;
+ emit guideLinesChanged( m_view );
+ }
+ emit moveGuides( false );
+ return eventProcessed;
+}
+
+
+bool KoGuides::keyPressEvent( QKeyEvent *e )
+{
+ bool eventProcessed = false;
+ switch( e->key() )
+ {
+ case Qt::Key_Delete:
+ if ( hasSelected() )
+ {
+ removeSelected();
+ paint();
+ emit guideLinesChanged( m_view );
+ eventProcessed = true;
+ }
+ break;
+ default:
+ break;
+ }
+ return eventProcessed;
+}
+
+void KoGuides::setGuideLines( const QValueList<double> &horizontalPos, const QValueList<double> &verticalPos )
+{
+ removeSelected();
+
+ QValueList<KoGuideLine *>::iterator it = m_guideLines[GL].begin();
+ for ( ; it != m_guideLines[GL].end(); ++it )
+ {
+ delete ( *it );
+ }
+ m_guideLines[GL].clear();
+
+ QValueList<double>::ConstIterator posIt = horizontalPos.begin();
+ for ( ; posIt != horizontalPos.end(); ++posIt )
+ {
+ KoGuideLine *guideLine = new KoGuideLine( Qt::Horizontal, *posIt, false );
+ m_guideLines[GL].append( guideLine );
+ }
+ posIt = verticalPos.begin();
+ for ( ; posIt != verticalPos.end(); ++posIt )
+ {
+ KoGuideLine *guideLine = new KoGuideLine( Qt::Vertical, *posIt, false );
+ m_guideLines[GL].append( guideLine );
+ }
+ paint();
+}
+
+void KoGuides::setAutoGuideLines( const QValueList<double> &horizontalPos, const QValueList<double> &verticalPos )
+{
+ QValueList<KoGuideLine *>::iterator it = m_guideLines[GL_AUTOMATIC].begin();
+ for ( ; it != m_guideLines[GL_AUTOMATIC].end(); ++it )
+ {
+ delete ( *it );
+ }
+ m_guideLines[GL_AUTOMATIC].clear();
+
+ QValueList<double>::ConstIterator posIt = horizontalPos.begin();
+ for ( ; posIt != horizontalPos.end(); ++posIt )
+ {
+ KoGuideLine *guideLine = new KoGuideLine( Qt::Horizontal, *posIt, true );
+ m_guideLines[GL_AUTOMATIC].append( guideLine );
+ }
+ posIt = verticalPos.begin();
+ for ( ; posIt != verticalPos.end(); ++posIt )
+ {
+ KoGuideLine *guideLine = new KoGuideLine( Qt::Vertical, *posIt, true );
+ m_guideLines[GL_AUTOMATIC].append( guideLine );
+ }
+}
+
+
+void KoGuides::getGuideLines( QValueList<double> &horizontalPos, QValueList<double> &verticalPos ) const
+{
+ horizontalPos.clear();
+ verticalPos.clear();
+
+ QValueList<KoGuideLine *>::const_iterator it = m_guideLines[GL].begin();
+ for ( ; it != m_guideLines[GL].end(); ++it )
+ {
+ if ( ( *it )->orientation == Qt::Horizontal )
+ {
+ horizontalPos.append( ( *it )->position );
+ }
+ else
+ {
+ verticalPos.append( ( *it )->position );
+ }
+ }
+ it = m_guideLines[GL_SELECTED].begin();
+ for ( ; it != m_guideLines[GL_SELECTED].end(); ++it )
+ {
+ if ( ( *it )->orientation == Qt::Horizontal )
+ {
+ horizontalPos.append( ( *it )->position );
+ }
+ else
+ {
+ verticalPos.append( ( *it )->position );
+ }
+ }
+}
+
+
+void KoGuides::snapToGuideLines( KoRect &rect, int snap, SnapStatus &snapStatus, KoPoint &diff )
+{
+ if( !(snapStatus & SNAP_VERT))
+ diff.setX(10000);
+ if( !(snapStatus & SNAP_HORIZ))
+ diff.setY(10000);
+
+ for ( int i = 0; i < GL_END; ++i )
+ {
+ QValueList<KoGuideLine *>::const_iterator it = m_guideLines[i].begin();
+ for ( ; it != m_guideLines[i].end(); ++it )
+ {
+ if ( ( *it )->orientation == Qt::Horizontal )
+ {
+ double tmp = (*it)->position - rect.top();
+ if ( snapStatus & SNAP_HORIZ || QABS( tmp ) < m_zoomHandler->unzoomItY( snap ) )
+ {
+ if(QABS( tmp ) < QABS(diff.y()))
+ {
+ diff.setY( tmp );
+ snapStatus |= SNAP_HORIZ;
+ }
+ }
+ tmp = (*it)->position - rect.bottom();
+ if ( snapStatus & SNAP_HORIZ || QABS( tmp ) < m_zoomHandler->unzoomItY( snap ) )
+ {
+ if(QABS( tmp ) < QABS(diff.y()))
+ {
+ diff.setY( tmp );
+ snapStatus |= SNAP_HORIZ;
+ }
+ }
+ }
+ else
+ {
+ double tmp = (*it)->position - rect.left();
+ if ( snapStatus & SNAP_VERT || QABS( tmp ) < m_zoomHandler->unzoomItX( snap ) )
+ {
+ if(QABS( tmp ) < QABS(diff.x()))
+ {
+ diff.setX( tmp );
+ snapStatus |= SNAP_VERT;
+ }
+ }
+ tmp = (*it)->position - rect.right();
+ if ( snapStatus & SNAP_VERT || QABS( tmp ) < m_zoomHandler->unzoomItX( snap ) )
+ {
+ if(QABS( tmp ) < QABS(diff.x()))
+ {
+ diff.setX( tmp );
+ snapStatus |= SNAP_VERT;
+ }
+ }
+ }
+ }
+ }
+
+ if(!(snapStatus & SNAP_VERT))
+ diff.setX( 0 );
+
+ if(!(snapStatus & SNAP_HORIZ))
+ diff.setY( 0 );
+}
+
+void KoGuides::snapToGuideLines( KoPoint &pos, int snap, SnapStatus &snapStatus, KoPoint &diff )
+{
+ if( !(snapStatus & SNAP_VERT))
+ diff.setX(10000);
+ if( !(snapStatus & SNAP_HORIZ))
+ diff.setY(10000);
+
+ for ( int i = 0; i < GL_END; ++i )
+ {
+ QValueList<KoGuideLine *>::const_iterator it = m_guideLines[i].begin();
+ for ( ; it != m_guideLines[i].end(); ++it )
+ {
+ if ( ( *it )->orientation == Qt::Horizontal )
+ {
+ double tmp = (*it)->position - pos.y();
+ if ( snapStatus & SNAP_HORIZ || QABS( tmp ) < m_zoomHandler->unzoomItY( snap ) )
+ {
+ if(QABS( tmp ) < QABS(diff.y()))
+ {
+ diff.setY( tmp );
+ snapStatus |= SNAP_HORIZ;
+ }
+ }
+ }
+ else
+ {
+ double tmp = (*it)->position - pos.x();
+ if ( snapStatus & SNAP_VERT || QABS( tmp ) < m_zoomHandler->unzoomItX( snap ) )
+ {
+ if(QABS( tmp ) < QABS(diff.x()))
+ {
+ diff.setX( tmp );
+ snapStatus |= SNAP_VERT;
+ }
+ }
+ }
+ }
+ }
+
+ if(!(snapStatus & SNAP_VERT))
+ diff.setX( 0 );
+
+ if(!(snapStatus & SNAP_HORIZ))
+ diff.setY( 0 );
+}
+
+
+void KoGuides::repaintSnapping( const KoRect &snappedRect )
+{
+ bool needRepaint = false;
+ for ( int i = 0; i < GL_END; ++i )
+ {
+ QValueList<KoGuideLine *>::const_iterator it = m_guideLines[i].begin();
+ for ( ; it != m_guideLines[i].end(); ++it )
+ {
+ if ( ( *it )->orientation == Qt::Horizontal )
+ {
+ if ( virtuallyEqual( snappedRect.top(), (*it)->position )
+ || virtuallyEqual( snappedRect.bottom(), ( *it )->position ) )
+ {
+ if ( ! ( *it )->snapping )
+ {
+ ( *it )->snapping = true;
+ needRepaint = true;
+ }
+ }
+ else if ( ( *it )->snapping )
+ {
+ ( *it )->snapping = false;
+ needRepaint = true;
+ }
+ }
+ else
+ {
+ if ( virtuallyEqual( snappedRect.left(), (*it)->position )
+ || virtuallyEqual( snappedRect.right(), ( *it )->position ) )
+ {
+ if ( ! ( *it )->snapping )
+ {
+ ( *it )->snapping = true;
+ needRepaint = true;
+ }
+ }
+ else if ( ( *it )->snapping )
+ {
+ ( *it )->snapping = false;
+ needRepaint = true;
+ }
+ }
+ }
+ }
+
+ if ( needRepaint )
+ {
+ emit paintGuides( true );
+ paint();
+ emit paintGuides( false );
+ }
+}
+
+
+void KoGuides::repaintSnapping( const KoPoint &snappedPoint, SnapStatus snapStatus )
+{
+ bool needRepaint = false;
+ for ( int i = 0; i < GL_END; ++i )
+ {
+ QValueList<KoGuideLine *>::const_iterator it = m_guideLines[i].begin();
+ for ( ; it != m_guideLines[i].end(); ++it )
+ {
+ if ( ( *it )->orientation == Qt::Horizontal && ( snapStatus & SNAP_HORIZ ) )
+ {
+ if( virtuallyEqual( snappedPoint.y(), (*it)->position ) )
+ {
+ if ( ! ( *it )->snapping )
+ {
+ ( *it )->snapping = true;
+ needRepaint = true;
+ }
+ }
+ else if ( ( *it )->snapping )
+ {
+ ( *it )->snapping = false;
+ needRepaint = true;
+ }
+ }
+ else
+ {
+ if ( snapStatus & SNAP_VERT )
+ {
+ if( virtuallyEqual( snappedPoint.x(), (*it)->position ) )
+ {
+ if ( ! ( *it )->snapping )
+ {
+ ( *it )->snapping = true;
+ needRepaint = true;
+ }
+ }
+ else if ( ( *it )->snapping )
+ {
+ ( *it )->snapping = false;
+ needRepaint = true;
+ }
+ }
+ }
+ }
+ }
+
+ if ( needRepaint )
+ {
+ emit paintGuides( true );
+ paint();
+ emit paintGuides( false );
+ }
+}
+
+
+void KoGuides::repaintAfterSnapping()
+{
+ bool needRepaint = false;
+
+ for ( int i = 0; i < GL_END; ++i )
+ {
+ QValueList<KoGuideLine *>::const_iterator it = m_guideLines[i].begin();
+ for ( ; it != m_guideLines[i].end(); ++it )
+ {
+ if ( ( *it )->snapping )
+ {
+ needRepaint = true;
+ ( *it )->snapping = false;
+ }
+ }
+ }
+
+ if ( needRepaint )
+ {
+ emit paintGuides( true );
+ paint();
+ emit paintGuides( false );
+ }
+}
+
+
+void KoGuides::diffNextGuide( KoRect &rect, KoPoint &diff )
+{
+ for ( int i = 0; i < GL_END; ++i )
+ {
+ QValueList<KoGuideLine *>::const_iterator it = m_guideLines[i].begin();
+ for ( ; it != m_guideLines[i].end(); ++it )
+ {
+ if ( ( *it )->orientation == Qt::Horizontal )
+ {
+ double moveyl = ( *it )->position - rect.top();
+ double moveyr = ( *it )->position - rect.bottom();
+ if ( diff.y() > 0 )
+ {
+ if ( moveyl < diff.y() && moveyl > 1E-10 )
+ {
+ diff.setY( moveyl );
+ }
+ if ( moveyr < diff.y() && moveyr > 1E-10 )
+ {
+ diff.setY( moveyr );
+ }
+ }
+ else if ( diff.y() < 0 )
+ {
+ if ( moveyl > diff.y() && moveyl < -1E-10 )
+ {
+ diff.setY( moveyl );
+ }
+ if ( moveyr > diff.y() && moveyr < -1E-10 )
+ {
+ diff.setY( moveyr );
+ }
+ }
+ }
+ else
+ {
+ double movexl = ( *it )->position - rect.left();
+ double movexr = ( *it )->position - rect.right();
+ if ( diff.x() > 0 )
+ {
+ if ( movexl < diff.x() && movexl > 1E-10 )
+ {
+ diff.setX( movexl );
+ }
+ if ( ( movexr < diff.x() ) && movexr > 1E-10 )
+ {
+ diff.setX( movexr );
+ }
+ }
+ else if ( diff.x() < 0 )
+ {
+ if ( movexl > diff.x() && movexl < -1E-10 )
+ {
+ diff.setX( movexl );
+ }
+ if ( movexr > diff.x() && movexr < -1E-10 )
+ {
+ diff.setX( movexr );
+ }
+ }
+ }
+ }
+ }
+}
+
+
+void KoGuides::moveGuide( const QPoint &pos, bool horizontal, int rulerWidth )
+{
+ int x = pos.x() - rulerWidth;
+ int y = pos.y() - rulerWidth;
+ QPoint p( x, y );
+ if ( !m_insertGuide )
+ {
+ if ( ! horizontal && x > 0 )
+ {
+ m_insertGuide = true;
+ add( Qt::Vertical, p );
+ }
+ else if ( horizontal && y > 0 )
+ {
+ m_insertGuide = true;
+ add( Qt::Horizontal, p );
+ }
+ if ( m_insertGuide )
+ {
+ QMouseEvent e( QEvent::MouseButtonPress, p, Qt::LeftButton, Qt::LeftButton );
+ mousePressEvent( &e );
+ }
+ }
+ else
+ {
+ QMouseEvent e( QEvent::MouseMove, p, Qt::NoButton, Qt::LeftButton );
+ mouseMoveEvent( &e );
+ }
+}
+
+
+void KoGuides::addGuide( const QPoint &pos, bool /* horizontal */, int rulerWidth )
+{
+ int x = pos.x() - rulerWidth;
+ int y = pos.y() - rulerWidth;
+ QPoint p( x, y );
+ m_insertGuide = false;
+ QMouseEvent e( QEvent::MouseButtonRelease, p, Qt::LeftButton, Qt::LeftButton );
+ mouseReleaseEvent( &e );
+}
+
+
+void KoGuides::slotChangePosition()
+{
+ KoPoint p( mapFromScreen( m_lastPoint ) );
+ KoGuideLine * guideLine = find( p, m_zoomHandler->unzoomItY( 2 ) );
+
+ const KoPageLayout& pl = m_view->koDocument()->pageLayout();
+ double max = 0.0;
+ if ( guideLine->orientation == Qt::Vertical )
+ {
+ max = QMAX( pl.ptWidth, m_zoomHandler->unzoomItX( m_view->canvas()->size().width() + m_view->canvasXOffset() - 1 ) );
+ }
+ else
+ {
+ max = QMAX( pl.ptHeight, m_zoomHandler->unzoomItY( m_view->canvas()->size().height() + m_view->canvasYOffset() - 1 ) );
+ }
+
+ KoGuideLineDia dia( 0, guideLine->position, 0.0, max, m_view->koDocument()->unit() );
+ if ( dia.exec() == QDialog::Accepted )
+ {
+ guideLine->position = dia.pos();
+ paint();
+ emit guideLinesChanged( m_view );
+ }
+}
+
+
+void KoGuides::slotRemove()
+{
+ removeSelected();
+ paint();
+}
+
+
+void KoGuides::paint()
+{
+ m_view->canvas()->repaint( false );
+}
+
+
+void KoGuides::add( Qt::Orientation o, QPoint &pos )
+{
+ KoPoint p( mapFromScreen( pos ) );
+ KoGuideLine *guideLine = new KoGuideLine( o, o == Qt::Vertical ? p.x(): p.y() );
+ m_guideLines[GL].append( guideLine );
+}
+
+
+void KoGuides::select( KoGuideLine *guideLine )
+{
+ guideLine->selected = true;
+ if ( m_guideLines[GL].remove( guideLine ) == 1 )
+ {
+ m_guideLines[GL_SELECTED].append( guideLine );
+ }
+}
+
+
+void KoGuides::unselect( KoGuideLine *guideLine )
+{
+ guideLine->selected = false;
+ if ( m_guideLines[GL_SELECTED].remove( guideLine ) == 1 )
+ {
+ m_guideLines[GL].append( guideLine );
+ }
+}
+
+
+bool KoGuides::unselectAll()
+{
+ bool selected = m_guideLines[GL_SELECTED].empty() == false;
+
+ QValueList<KoGuideLine *>::iterator it = m_guideLines[GL_SELECTED].begin();
+ for ( ; it != m_guideLines[GL_SELECTED].end(); ++it )
+ {
+ ( *it )->selected = false;
+ m_guideLines[GL].append( *it );
+ }
+ m_guideLines[GL_SELECTED].clear();
+
+ return selected;
+}
+
+
+void KoGuides::removeSelected()
+{
+ QValueList<KoGuideLine *>::iterator it = m_guideLines[GL_SELECTED].begin();
+ for ( ; it != m_guideLines[GL_SELECTED].end(); ++it )
+ {
+ delete ( *it );
+ }
+ m_guideLines[GL_SELECTED].clear();
+}
+
+
+bool KoGuides::hasSelected()
+{
+ return m_guideLines[GL_SELECTED].empty() == false;
+}
+
+
+KoGuides::KoGuideLine * KoGuides::find( KoPoint &p, double diff )
+{
+ QValueList<KoGuideLine *>::iterator it = m_guideLines[GL_SELECTED].begin();
+ for ( ; it != m_guideLines[GL_SELECTED].end(); ++it )
+ {
+ if ( ( *it )->orientation == Qt::Vertical && QABS( ( *it )->position - p.x() ) < diff )
+ {
+ return *it;
+ }
+ if ( ( *it )->orientation == Qt::Horizontal && QABS( ( *it )->position - p.y() ) < diff )
+ {
+ return *it;
+ }
+ }
+
+ it = m_guideLines[GL].begin();
+ for ( ; it != m_guideLines[GL].end(); ++it )
+ {
+ if ( ( *it )->orientation == Qt::Vertical && QABS( ( *it )->position - p.x() ) < diff )
+ {
+ return *it;
+ }
+ if ( ( *it )->orientation == Qt::Horizontal && QABS( ( *it )->position - p.y() ) < diff )
+ {
+ return *it;
+ }
+ }
+ return 0;
+}
+
+
+void KoGuides::moveSelectedBy( QPoint &p )
+{
+ KoPoint point( m_zoomHandler->unzoomPoint( p ) );
+ if ( m_guideLines[GL_SELECTED].count() > 1 )
+ {
+ const KoPageLayout& pl = m_view->koDocument()->pageLayout();
+ double right = QMAX( pl.ptWidth, m_zoomHandler->unzoomItX( m_view->canvas()->width() + m_view->canvasXOffset() - 1 ) );
+ double bottom = QMAX( pl.ptHeight, m_zoomHandler->unzoomItY( m_view->canvas()->height() + m_view->canvasYOffset() - 1 ) );
+
+ QValueList<KoGuideLine *>::iterator it = m_guideLines[GL_SELECTED].begin();
+ for ( ; it != m_guideLines[GL_SELECTED].end(); ++it )
+ {
+ if ( ( *it )->orientation == Qt::Vertical )
+ {
+ double tmp = ( *it )->position + point.x();
+ if ( tmp < 0 )
+ {
+ point.setX( point.x() - tmp );
+ }
+ else if ( tmp > right )
+ {
+ point.setX( point.x() - ( tmp - right ) );
+ }
+ }
+ else
+ {
+ double tmp = ( *it )->position + point.y();
+ if ( tmp < 0 )
+ {
+ point.setY( point.y() - tmp );
+ }
+ else if ( tmp > bottom )
+ {
+ point.setY( point.y() - ( tmp - bottom ) );
+ }
+ }
+ }
+ }
+ QValueList<KoGuideLine *>::iterator it = m_guideLines[GL_SELECTED].begin();
+ for ( ; it != m_guideLines[GL_SELECTED].end(); ++it )
+ {
+ ( *it )->snapping = false;
+
+ if ( ( *it )->orientation == Qt::Vertical && p.x() != 0 )
+ {
+ ( *it )->position = ( *it )->position + point.x();
+ }
+ else if ( ( *it )->orientation == Qt::Horizontal && p.y() != 0 )
+ {
+ ( *it )->position = ( *it )->position + point.y();
+ }
+ }
+}
+
+
+KoPoint KoGuides::mapFromScreen( const QPoint & pos )
+{
+ int x = pos.x() + m_view->canvasXOffset();
+ int y = pos.y() + m_view->canvasYOffset();
+ double xf = m_zoomHandler->unzoomItX( x );
+ double yf = m_zoomHandler->unzoomItY( y );
+ return KoPoint( xf, yf );
+}
+
+
+QPoint KoGuides::mapToScreen( const KoPoint & pos )
+{
+ int x = m_zoomHandler->zoomItX( pos.x() ) - m_view->canvasXOffset();
+ int y = m_zoomHandler->zoomItY( pos.y() ) - m_view->canvasYOffset();
+ return QPoint( x, y );
+}
+
+
+#include "KoGuides.moc"
diff --git a/lib/kofficeui/KoGuides.h b/lib/kofficeui/KoGuides.h
new file mode 100644
index 00000000..c084c013
--- /dev/null
+++ b/lib/kofficeui/KoGuides.h
@@ -0,0 +1,421 @@
+// -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4; -*-
+/* This file is part of the KDE project
+ Copyright (C) 2005 Thorsten Zachmann <zachmann@kde.org>
+ Copyright (C) 2005 Casper Boemann Rasmussen <cbr@boemann.dk>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KOGUIDES_H
+#define KOGUIDES_H
+
+#include <qevent.h>
+#include <qobject.h>
+
+#include <koffice_export.h>
+
+class QPaintDevice;
+class KoPoint;
+class KoRect;
+class KoView;
+class KoZoomHandler;
+
+class KOFFICEUI_EXPORT KoGuides : public QObject
+{
+ Q_OBJECT
+public:
+ /**
+ * @brief Constructor
+ *
+ * @param view The view in which the guides will be shown
+ * @param zoomHandler The zoom handler of the view
+ */
+ KoGuides( KoView *view, KoZoomHandler *zoomHandler );
+
+ /**
+ * @brief Destructor
+ */
+ ~KoGuides();
+
+ /**
+ * @brief Paint the guides
+ *
+ * @param painter with which the guides are painted
+ */
+ void paintGuides( QPainter &painter );
+
+ typedef int SnapStatus;
+ static const SnapStatus SNAP_NONE, SNAP_HORIZ, SNAP_VERT, SNAP_BOTH;
+
+ /**
+ * @brief Handle mousePressEvent
+ *
+ * This checks if a mousePressEvent would affect a guide line.
+ * If the mouse is pressed over a guide line it gets selected.
+ * Guide lines which were select get unselect.
+ * If also the Ctrl Key is pressed the selection of the guide
+ * gets toggled.
+ * If no guide is under the position all guides get deselected.
+ *
+ * @param e QMouseEvent
+ *
+ * @return true if the event was handled
+ * @return false otherwise
+ * The event counts a not handled when only guides where
+ * deselected.
+ */
+ bool mousePressEvent( QMouseEvent *e );
+
+ /**
+ * @brief Handle mouseMoveEvent
+ *
+ * If the mouse button is pressed and a guide was selected it moves the
+ * selected guides.
+ * If the mouse is moved over a guide line the cursor gets updated.
+ *
+ * @param e QMouseEvent
+ *
+ * @return true if the event was handled (guide moved, cursor changed as
+ * guide lies below)
+ * @return false otherwise
+ */
+ bool mouseMoveEvent( QMouseEvent *e );
+
+ /**
+ *
+ * @param e QMouseEvent
+ *
+ * @return true if the event was handled
+ * @return false otherwise
+ */
+ bool mouseReleaseEvent( QMouseEvent *e );
+
+ /**
+ *
+ * @param e QKeyEvent
+ *
+ * @return true if the event was handled
+ * @return false otherwise
+ */
+ bool keyPressEvent( QKeyEvent *e );
+
+ /**
+ * @brief Set the guide lines.
+ *
+ * This removes all existing guides and set up new ones at the positions given.
+ *
+ * @param horizontalPos A list of the position of the horizontal guide lines.
+ * @param verticalPos A list of the position of the vertical guide lines.
+ */
+ void setGuideLines( const QValueList<double> &horizontalPos, const QValueList<double> &verticalPos );
+
+ /**
+ * @brief Set the positions for snapping of auto guide lines
+ *
+ * This removes all existing auto guide lines and set up new ones at the positions given.
+ *
+ * @param horizontalPos A list of the position of the horizontal guide lines.
+ * @param verticalPos A list of the position of the vertical guide lines.
+ */
+ void setAutoGuideLines( const QValueList<double> &horizontalPos, const QValueList<double> &verticalPos );
+
+ /**
+ * @brief Get the position of the guide lines
+ *
+ * This filles the passed lists with the positions of the guide lines.
+ * The lists will be emptied before any positions are added.
+ *
+ * @param horizontalPos A list of the position of the horizontal guide lines.
+ * @param verticalPos A list of the position of the vertical guide lines.
+ */
+ void getGuideLines( QValueList<double> &horizontalPos, QValueList<double> &verticalPos ) const;
+
+ /**
+ * @brief Snap rect to guidelines
+ *
+ * This looks for a guide which is in reach for the guide as defined in snap.
+ * This method has the abillity to combine more calls. The snapStatus and diff args are both input and
+ * output. On first call you should set snapStatus to 0. The return value would then show in which
+ * directions it has snapped. If you combine several KoGuides you can let these output arguments
+ * be input for the next koGuide. That way you'll always catch the nearest guide.
+ *
+ * @param rect the rect which should be snapped
+ * @param snap the distance within the guide should snap - but always snap if already snapped
+ * @param snapStatus if horiz,vert or both directions are snapped (both in and out param).
+ * @param diff distance away from guide. Only valid if status is snapping (both in and out param)
+ */
+ void snapToGuideLines( KoRect &rect, int snap, SnapStatus &snapStatus, KoPoint &diff );
+
+ /**
+ * @brief Snap rect to guidelines
+ *
+ * This looks fo a guide which is in reach for the guide as defined in snap.
+ *
+ * @param pos the position which should be snapped
+ * @param snap the distance wherein the guide should snap - but always snap if already snapped
+ * @param snapStatus if horiz,vert or both directions are snapped (both in and out param)
+ * @param diff distance away from guide. Only valid if status is snapping (both in and out param)
+ */
+ void snapToGuideLines( KoPoint &pos, int snap, SnapStatus &snapStatus, KoPoint &diff );
+
+ /**
+ * @brief repaint guides if any changed snapping status
+ *
+ * This issues a paint request if any guides have changed snapping status.
+ *
+ * @param snappedRect the rect after it has been snapped
+ */
+ void repaintSnapping( const KoRect &snappedRect );
+
+ /**
+ * @brief repaint guides if any changed snapping status
+ *
+ * This issues a paint request if any guides have changed snapping status.
+ *
+ * @param snappedPoint the point after it has been snapped
+ */
+ void repaintSnapping( const KoPoint &snappedPoint, SnapStatus snapStatus );
+
+ /**
+ * @brief repaint guides so none is snapped
+ *
+ * This issues a paint request if any guides have changed snapping status.
+ * It also effectively un-snaps all since it doesn't take an argument
+ */
+ void repaintAfterSnapping( );
+
+ /**
+ * @brief Find the closesed disance to the next guide within the given distance
+ *
+ * @param rect The rect which should be snapped
+ * @param diff distance in which too look for the closesed guide. The parameter is updated
+ * with the closesed distance to a guide if one is found (both in and out param)
+ */
+ void diffNextGuide( KoRect &rect, KoPoint &diff );
+
+public slots:
+ /**
+ * @brief Move Guide
+ *
+ * This slot can be connected to void KoRuler::moveGuide( const QPoint &, bool, int );
+ * It will add a new guide when you move from the ruler to the canvas. After that it
+ * moves the guide.
+ *
+ * @param pos The pos of the mouse
+ * @param horizontal true if the guide is horizontal, false if vertical
+ * @param rulerWidth The witdth of the ruler as the pos is seen from the ruler widget.
+ */
+ void moveGuide( const QPoint &pos, bool horizontal, int rulerWidth );
+
+ /**
+ * @brief Add Guide
+ *
+ * This slot can be connected to void KoRuler::addGuide( const QPoint &, bool, int );
+ * It will finish the inserting of a guide from moveGuide().
+ *
+ * @param pos The pos of the mouse
+ * @param horizontal true if the guide is horizontal, false if vertical
+ * @param rulerWidth The witdth of the ruler as the pos is seen from the ruler widget.
+ */
+ void addGuide( const QPoint &pos, bool horizontal, int rulerWidth );
+
+signals:
+ /**
+ * @brief Signal that shows that the guide lines are changed
+ *
+ * This signal is emmited when the guide lines are changed ( moved / deleted )
+ *
+ * @param view The view in which the guide lines are changed.
+ */
+ void guideLinesChanged( KoView * view );
+
+ /**
+ * @brief This signal is emitted when guides start/stop moving.
+ *
+ * @param state true when starting moving guides, false when stopping.
+ */
+ void moveGuides( bool state );
+
+ /**
+ * @brief This signal is emitted when guides start/stop painting.
+ *
+ * With this signal it is possible to only repaint the guides in the paint
+ * method of the canvas. Just set/unset a flag when this signal is emmited.
+ * This signal is emitted before and after a repaint is done.
+ *
+ * @param state true when starting painting guides, false when stopping.
+ */
+ void paintGuides( bool state );
+
+private slots:
+ /**
+ * @brief Execute a dialog to set the position of the guide
+ */
+ void slotChangePosition();
+
+ /**
+ * @brief remove all selected guides
+ */
+ void slotRemove();
+
+private:
+ /// Strukt holding the data of a guide line
+ struct KoGuideLine
+ {
+ KoGuideLine( Qt::Orientation o, double pos, bool a = false )
+ : orientation( o )
+ , position( pos )
+ , selected( false )
+ , snapping( false )
+ , automatic( a )
+ {}
+ Qt::Orientation orientation;
+ double position;
+ bool selected; // if this guide is selected
+ bool snapping; // if this guide is being snapped to
+ bool automatic; // if this is a atomatic guide line
+ };
+
+ /**
+ * @brief Paint the canvas
+ */
+ void paint();
+
+ /**
+ * @brief Add a guide line with the orientation o at the position pos
+ *
+ * @param pos where to insert the guide
+ * @param o orientation of the guide line
+ */
+ void add( Qt::Orientation o, QPoint &pos );
+
+ /**
+ * @brief Select a guide
+ *
+ * @param gd guide to select
+ */
+ void select( KoGuideLine *guideLine );
+
+ /**
+ * @brief Unselect a guide
+ *
+ * @param gd guide to unselect
+ */
+ void unselect( KoGuideLine *guideLine );
+
+ /**
+ * @brief Unselect all selected KoGuideLineData
+ *
+ * @return true, when selection was changed
+ * @return false otherwise
+ */
+ bool unselectAll();
+
+ /**
+ * @brief remove all selected guides
+ */
+ void removeSelected();
+
+ /**
+ * @brief Check if at least one guide is selected
+ *
+ * @return true if at least on guide is seleted
+ * @return false otherwise
+ */
+ bool hasSelected();
+
+ /**
+ * @brief Find a guide
+ *
+ * This function looks for a guide at x or y pos. The position can differ by
+ * diff.
+ *
+ * @param x x position to look for a guide
+ * @param y y position to look for a guide
+ * @param diff how far next to a guide sould it also be found
+ *
+ * @return the fould guide
+ * @return 0 if none is found
+ */
+ KoGuideLine * find( KoPoint &p, double diff );
+
+ /**
+ * @brief Move selected guides.
+ *
+ * This moves all selected guides around. If more than one guide is selected it makes
+ * sure the guides are not moved of the canvas.
+ *
+ * @param pos position of the mouse
+ */
+ void moveSelectedBy( QPoint &p );
+
+ /**
+ * @brief Map pos from screen
+ *
+ * @param pos on screen
+ *
+ * @return pos in document
+ */
+ KoPoint mapFromScreen( const QPoint & pos );
+
+ /**
+ * @brief Map pos to screen
+ *
+ * @param pos in document
+ *
+ * @return pos on screen
+ */
+ QPoint mapToScreen( const KoPoint & pos );
+
+ /**
+ * @brief Check if the both values are nearly the same.
+ *
+ * @param a first value
+ * @param a second value
+ *
+ * @return true if they are the same
+ * @return false otherwise
+ */
+ bool virtuallyEqual( double a, double b ) { return QABS( a - b ) < 1E-4; }
+
+ /// view
+ KoView * m_view;
+ /// zoom handler of the view
+ KoZoomHandler * m_zoomHandler;
+
+ enum GuideLineType
+ {
+ GL,
+ GL_SELECTED,
+ GL_AUTOMATIC,
+ GL_END
+ };
+
+ /// array of list of the different guide line types
+ QValueList<KoGuideLine *> m_guideLines[GL_END];
+
+ /// used to save the last mouse position
+ QPoint m_lastPoint;
+ /// true if a guide is selected at the moment
+ bool m_mouseSelected;
+ /// true if a guide is inserted at the moment
+ bool m_insertGuide;
+ /// popup menu
+ class Popup;
+ Popup * m_popup;
+};
+
+#endif /* KOGUIDES_H */
diff --git a/lib/kofficeui/KoImageResource.cpp b/lib/kofficeui/KoImageResource.cpp
new file mode 100644
index 00000000..9f92ef3d
--- /dev/null
+++ b/lib/kofficeui/KoImageResource.cpp
@@ -0,0 +1,117 @@
+/*
+ * koImageResource.cc - part of KOffice
+ *
+ * Copyright (c) 2005 Thomas Zander <zander@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation;version 2.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "KoImageResource.h"
+
+namespace {
+ /* XPM -- copyright The Gimp */
+ const char *chain_broken_24[] = {
+ /* columns rows colors chars-per-pixel */
+ "9 24 10 1",
+ " c black",
+ ". c #020204",
+ "X c #5A5A5C",
+ "o c gray43",
+ "O c #8F8F91",
+ "+ c #9A9A98",
+ "@ c #B5B5B6",
+ "# c #D0D0D1",
+ "$ c #E8E8E9",
+ "% c None",
+ /* pixels */
+ "%%.....%%",
+ "%.o##@X.%",
+ "%.+...$.%",
+ "%.#.%.#.%",
+ "%.#.%.#.%",
+ "%.@.%.#.%",
+ "%.+...#.%",
+ "%.O.o.O.%",
+ "%%..@..%%",
+ "%%%.#.%%%",
+ "%%%%%%%%%",
+ "%%%%%%%%%",
+ "%%%%%%%%%",
+ "%%%%%%%%%",
+ "%%%.#.%%%",
+ "%%..#..%%",
+ "%.o.@.O.%",
+ "%.@...@.%",
+ "%.@.%.$.%",
+ "%.@.%.$.%",
+ "%.@.%.$.%",
+ "%.#...$.%",
+ "%.o$#$@.%",
+ "%%.....%%"
+ };
+
+ /* XPM -- copyright The Gimp */
+ const char *chain_24[] = {
+ /* columns rows colors chars-per-pixel */
+ "9 24 10 1",
+ " c black",
+ ". c #020204",
+ "X c #5A5A5C",
+ "o c gray43",
+ "O c #8F8F91",
+ "+ c #9A9A98",
+ "@ c #B5B5B6",
+ "# c #D0D0D1",
+ "$ c #E8E8E9",
+ "% c None",
+ /* pixels */
+ "%%%%%%%%%",
+ "%%%%%%%%%",
+ "%%.....%%",
+ "%.o##@X.%",
+ "%.+...$.%",
+ "%.#.%.#.%",
+ "%.#.%.#.%",
+ "%.@.%.#.%",
+ "%.+...#.%",
+ "%.O.o.O.%",
+ "%%..@..%%",
+ "%%%.#.%%%",
+ "%%%.#.%%%",
+ "%%..#..%%",
+ "%.o.@.O.%",
+ "%.@...@.%",
+ "%.@.%.$.%",
+ "%.@.%.$.%",
+ "%.@.%.$.%",
+ "%.#...$.%",
+ "%.o$#$@.%",
+ "%%.....%%",
+ "%%%%%%%%%",
+ "%%%%%%%%%"
+ };
+}
+
+KoImageResource::KoImageResource() {}
+
+const char** KoImageResource::chain()
+{
+ return chain_24;
+}
+
+const char** KoImageResource::chainBroken()
+{
+ return chain_broken_24;
+}
diff --git a/lib/kofficeui/KoImageResource.h b/lib/kofficeui/KoImageResource.h
new file mode 100644
index 00000000..97781c91
--- /dev/null
+++ b/lib/kofficeui/KoImageResource.h
@@ -0,0 +1,38 @@
+/*
+ * koImageResource.h - part of KOffice
+ *
+ * Copyright (c) 2005 Thomas Zander <zander@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation;version 2.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __ko_imageresource__
+#define __ko_imageresource__
+#include <koffice_export.h>
+
+class KOFFICEUI_EXPORT KoImageResource
+{
+
+public:
+
+ KoImageResource();
+
+ /// returns a 24 pixels xpm-format image of a chain.
+ const char** chain();
+ /// returns a 24 pixels xpm-format image of a broken chain.
+ const char** chainBroken();
+};
+#endif // __ko_imageresource__
+
diff --git a/lib/kofficeui/KoInsertLink.cpp b/lib/kofficeui/KoInsertLink.cpp
new file mode 100644
index 00000000..56c19081
--- /dev/null
+++ b/lib/kofficeui/KoInsertLink.cpp
@@ -0,0 +1,549 @@
+/* This file is part of the KDE project
+ Copyright (C) 2001 Montel Laurent <lmontel@mandrakesoft.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#include <kapplication.h>
+#include <klocale.h>
+
+#include <qlayout.h>
+#include <qvbox.h>
+#include <kdebug.h>
+#include <qlabel.h>
+#include <qcombobox.h>
+
+#include <klineedit.h>
+#include <kurlrequester.h>
+#include <kseparator.h>
+#include <kiconloader.h>
+#include "KoInsertLink.h"
+#include <kdesktopfile.h>
+#include <krecentdocument.h>
+
+using namespace KOfficePrivate;
+
+KoInsertLinkDia::KoInsertLinkDia( QWidget *parent, const char *name, bool displayBookmarkLink )
+ : KDialogBase( KDialogBase::IconList, i18n("Insert Link"),
+ KDialogBase::Ok | KDialogBase::Cancel,
+ KDialogBase::Ok, parent, name )
+{
+ bookmarkLink = 0L;
+ QVBox *page=addVBoxPage(i18n("Internet"), QString::null,BarIcon("html",KIcon::SizeMedium));
+ internetLink = new internetLinkPage(page );
+ connect(internetLink,SIGNAL(textChanged()),this,SLOT(slotTextChanged ( )));
+
+ page=addVBoxPage(i18n("Mail & News"), QString::null,BarIcon("mail_generic",KIcon::SizeMedium));
+ mailLink = new mailLinkPage(page );
+ connect(mailLink,SIGNAL(textChanged()),this,SLOT(slotTextChanged ()));
+
+ page=addVBoxPage(i18n("File"), QString::null,BarIcon("filenew",KIcon::SizeMedium));
+ fileLink = new fileLinkPage(page );
+ connect(fileLink,SIGNAL(textChanged()),this,SLOT(slotTextChanged ()));
+
+ if ( displayBookmarkLink)
+ {
+ page=addVBoxPage(i18n("Bookmark"), QString::null,BarIcon("bookmark",KIcon::SizeMedium));
+ bookmarkLink = new bookmarkLinkPage(page );
+ connect(bookmarkLink,SIGNAL(textChanged()),this,SLOT(slotTextChanged ()));
+ }
+
+ connect( this, SIGNAL( aboutToShowPage(QWidget *) ), this, SLOT( tabChanged(QWidget *) ) );
+
+ slotTextChanged ( );
+ resize(400,300);
+}
+
+void KoInsertLinkDia::tabChanged(QWidget *)
+{
+ switch( activePageIndex() )
+ {
+ case 0:
+ internetLink->setLinkName( currentText );
+ break;
+ case 1:
+ mailLink->setLinkName( currentText );
+ break;
+ case 2:
+ fileLink->setLinkName( currentText );
+ break;
+ case 3:
+ {
+ if ( bookmarkLink)
+ bookmarkLink->setLinkName( currentText );
+ }
+ break;
+ default:
+ kdDebug()<<"Error in linkName\n";
+ }
+ enableButtonOK( !(linkName().isEmpty() || hrefName().isEmpty()) );
+}
+
+void KoInsertLinkDia::slotTextChanged ( )
+{
+ enableButtonOK( !(linkName().isEmpty() || hrefName().isEmpty()));
+ currentText = linkName();
+}
+
+bool KoInsertLinkDia::createLinkDia(QString & _linkName, QString & _hrefName, const QStringList& bkmlist, bool displayBookmarkLink, QWidget* parent, const char* name)
+{
+ bool res = false;
+
+ KoInsertLinkDia *dlg = new KoInsertLinkDia( parent, name, displayBookmarkLink );
+ dlg->setHrefLinkName(_hrefName,_linkName, bkmlist);
+ if ( dlg->exec() == Accepted )
+ {
+ _linkName = dlg->linkName();
+ _hrefName = dlg->hrefName();
+ res = true;
+ }
+ delete dlg;
+
+ return res;
+}
+
+void KoInsertLinkDia::setHrefLinkName(const QString &_href, const QString &_link, const QStringList & bkmlist)
+{
+ if ( bookmarkLink)
+ bookmarkLink->setBookmarkList(bkmlist);
+ if ( _href.isEmpty())
+ {
+ if ( !_link.isEmpty() )
+ {
+ internetLink->setLinkName(_link);
+ showPage(0);
+ slotTextChanged ( );
+ }
+ return;
+ }
+ if(_href.find("http://")!=-1 || _href.find("https://")!=-1 ||_href.find("ftp://")!=-1 )
+ {
+ internetLink->setHrefName(_href);
+ internetLink->setLinkName(_link);
+ showPage(0);
+ }
+ else if(_href.find("file:/")!=-1)
+ {
+ fileLink->setHrefName(_href);
+ fileLink->setLinkName(_link);
+ showPage(2);
+ }
+ else if(_href.find("mailto:")!=-1 || _href.find("news:")!=-1)
+ {
+ mailLink->setHrefName(_href);
+ mailLink->setLinkName(_link);
+ showPage(1);
+ }
+ else if(_href.find("bkm://")!=-1)
+ {
+ if ( bookmarkLink )
+ {
+ bookmarkLink->setHrefName(_href.mid(6));
+ bookmarkLink->setLinkName(_link);
+ showPage(3);
+ }
+ }
+ slotTextChanged ( );
+}
+
+QString KoInsertLinkDia::linkName() const
+{
+ QString result;
+ switch(activePageIndex())
+ {
+ case 0:
+ result=internetLink->linkName();
+ break;
+ case 1:
+ result=mailLink->linkName();
+ break;
+ case 2:
+ result=fileLink->linkName();
+ break;
+ case 3:
+ {
+ if ( bookmarkLink)
+ result=bookmarkLink->linkName();
+ }
+ break;
+ default:
+ kdDebug()<<"Error in linkName\n";
+ }
+ return result;
+}
+
+QString KoInsertLinkDia::hrefName() const
+{
+ QString result;
+ switch(activePageIndex())
+ {
+ case 0:
+ result=internetLink->hrefName();
+ break;
+ case 1:
+ result=mailLink->hrefName();
+ break;
+ case 2:
+ result=fileLink->hrefName();
+ break;
+ case 3:
+ {
+ if ( bookmarkLink )
+ result=bookmarkLink->hrefName();
+ }
+ break;
+ default:
+ kdDebug()<<"Error in hrefName\n";
+ }
+ return result;
+}
+
+void KoInsertLinkDia::slotOk()
+{
+ KDialogBase::slotOk();
+}
+
+
+internetLinkPage::internetLinkPage( QWidget *parent , char *name )
+ : QWidget(parent,name)
+{
+ QVBoxLayout *lay1 = new QVBoxLayout( this );
+ lay1->setSpacing( KDialog::spacingHint() );
+ QVBoxLayout *lay2 = new QVBoxLayout( lay1);
+ lay2->setSpacing( KDialog::spacingHint() );
+
+ QLabel* tmpQLabel = new QLabel( this);
+
+ lay2->addWidget(tmpQLabel);
+ tmpQLabel->setText(i18n("Text to display:"));
+
+ m_linkName = new QLineEdit( this );
+ lay2->addWidget(m_linkName);
+
+ tmpQLabel = new QLabel( this);
+ lay2->addWidget(tmpQLabel);
+
+ tmpQLabel->setText(i18n("Internet address:"));
+ m_hrefName = new QLineEdit( this );
+
+ lay2->addWidget(m_hrefName);
+
+ lay2->addStretch( 1 );
+
+ m_linkName->setFocus();
+
+ connect(m_linkName,SIGNAL(textChanged ( const QString & )),this,SLOT(textChanged ( const QString & )));
+ connect(m_hrefName,SIGNAL(textChanged ( const QString & )),this,SLOT(textChanged ( const QString & )));
+ KSeparator* bar1 = new KSeparator( KSeparator::HLine, this);
+ bar1->setFixedHeight( 10 );
+ lay2->addWidget( bar1 );
+}
+
+QString internetLinkPage::createInternetLink()
+{
+ QString result=m_hrefName->text();
+
+ if(result.isEmpty())
+ return result;
+
+ if(result.find("http://")==-1 && result.find("https://")==-1 && result.find("ftp://")==-1)
+ result = "http://"+result;
+ return result;
+}
+
+
+void internetLinkPage::setLinkName(const QString & _name)
+{
+ m_linkName->setText(_name);
+}
+
+void internetLinkPage::setHrefName(const QString &_name)
+{
+ m_hrefName->setText(_name);
+}
+
+QString internetLinkPage::linkName()const
+{
+ return m_linkName->text();
+}
+
+QString internetLinkPage::hrefName()
+{
+ return createInternetLink();
+}
+
+void internetLinkPage::textChanged ( const QString & )
+{
+ emit textChanged();
+}
+
+bookmarkLinkPage::bookmarkLinkPage( QWidget *parent , char *name )
+ : QWidget(parent,name)
+{
+ QVBoxLayout *lay1 = new QVBoxLayout( this );
+ lay1->setSpacing( KDialog::spacingHint() );
+ QVBoxLayout *lay2 = new QVBoxLayout( lay1);
+ lay2->setSpacing( KDialog::spacingHint() );
+
+ QLabel* tmpQLabel = new QLabel( this);
+
+ lay2->addWidget(tmpQLabel);
+ tmpQLabel->setText(i18n("Text to display:"));
+
+ m_linkName = new QLineEdit( this );
+ lay2->addWidget(m_linkName);
+
+ tmpQLabel = new QLabel( this);
+ lay2->addWidget(tmpQLabel);
+
+ tmpQLabel->setText(i18n("Bookmark name:"));
+ m_hrefName = new QComboBox( this );
+
+ lay2->addWidget(m_hrefName);
+
+ lay2->addStretch( 1 );
+
+ m_linkName->setFocus();
+
+ connect(m_linkName,SIGNAL(textChanged ( const QString & )),this,SLOT(textChanged ( const QString & )));
+ connect(m_hrefName,SIGNAL(textChanged ( const QString & )),this,SLOT(textChanged ( const QString & )));
+ KSeparator* bar1 = new KSeparator( KSeparator::HLine, this);
+ bar1->setFixedHeight( 10 );
+ lay2->addWidget( bar1 );
+}
+
+QString bookmarkLinkPage::createBookmarkLink()
+{
+ QString result=m_hrefName->currentText();
+
+ if(result.isEmpty())
+ return result;
+
+ if(result.find("bkm://")==-1)
+ result = "bkm://"+result;
+ return result;
+}
+
+
+void bookmarkLinkPage::setLinkName(const QString & _name)
+{
+ m_linkName->setText(_name);
+}
+
+void bookmarkLinkPage::setHrefName(const QString &_name)
+{
+ m_hrefName->setCurrentText(_name);
+}
+
+void bookmarkLinkPage::setBookmarkList(const QStringList & bkmlist)
+{
+ m_hrefName->clear();
+ m_hrefName->insertStringList(bkmlist, 0);
+ if ( bkmlist.isEmpty())
+ m_linkName->setEnabled( false);
+ //m_hrefName->setEditable(true);
+}
+
+QString bookmarkLinkPage::linkName()const
+{
+ return m_linkName->text();
+}
+
+QString bookmarkLinkPage::hrefName()
+{
+ return createBookmarkLink();
+}
+
+void bookmarkLinkPage::textChanged ( const QString & )
+{
+ emit textChanged();
+}
+
+mailLinkPage::mailLinkPage( QWidget *parent , char *name )
+ : QWidget(parent,name)
+{
+ QVBoxLayout *lay1 = new QVBoxLayout( this );
+ lay1->setSpacing( KDialog::spacingHint() );
+ QVBoxLayout *lay2 = new QVBoxLayout( lay1);
+ lay2->setSpacing( KDialog::spacingHint() );
+
+ QLabel* tmpQLabel = new QLabel( this);
+
+ lay2->addWidget(tmpQLabel);
+ tmpQLabel->setText(i18n("Text to display:"));
+
+ m_linkName = new QLineEdit( this );
+ lay2->addWidget(m_linkName);
+
+ tmpQLabel = new QLabel( this);
+ lay2->addWidget(tmpQLabel);
+
+ tmpQLabel->setText(i18n("Target:"));
+ m_hrefName = new QLineEdit( this );
+
+ lay2->addWidget(m_hrefName);
+ lay2->addStretch( 1 );
+
+ connect(m_linkName,SIGNAL(textChanged ( const QString & )),this,SLOT(textChanged ( const QString & )));
+ connect(m_hrefName,SIGNAL(textChanged ( const QString & )),this,SLOT(textChanged ( const QString & )));
+ KSeparator* bar1 = new KSeparator( KSeparator::HLine, this);
+ bar1->setFixedHeight( 10 );
+ lay2->addWidget( bar1 );
+}
+
+QString mailLinkPage::createMailLink()
+{
+ QString result=m_hrefName->text();
+
+ if(result.isEmpty())
+ return result;
+
+ if(result.find("mailto:")==-1 && result.find("news:")==-1)
+ result = "mailto:"+result;
+ return result;
+}
+
+
+void mailLinkPage::setLinkName(const QString & _name)
+{
+ m_linkName->setText(_name);
+}
+
+void mailLinkPage::setHrefName(const QString &_name)
+{
+ m_hrefName->setText(_name);
+}
+
+QString mailLinkPage::linkName()const
+{
+ return m_linkName->text();
+}
+
+QString mailLinkPage::hrefName()
+{
+ return createMailLink();
+}
+
+void mailLinkPage::textChanged ( const QString & )
+{
+ emit textChanged();
+}
+
+fileLinkPage::fileLinkPage( QWidget *parent , char *name )
+ : QWidget(parent,name)
+{
+ QVBoxLayout *lay1 = new QVBoxLayout( this );
+ lay1->setSpacing( KDialog::spacingHint() );
+ QVBoxLayout *lay2 = new QVBoxLayout( lay1);
+ lay2->setSpacing( KDialog::spacingHint() );
+
+ QLabel* tmpQLabel = new QLabel( this);
+
+ lay2->addWidget(tmpQLabel);
+ tmpQLabel->setText(i18n("Text to display:"));
+
+ m_linkName = new QLineEdit( this );
+ lay2->addWidget(m_linkName);
+
+ tmpQLabel = new QLabel( this);
+ lay2->addWidget(tmpQLabel);
+ tmpQLabel->setText(i18n("Recent file:"));
+
+ QComboBox * recentFile = new QComboBox( this );
+ recentFile->setMaximumWidth( kapp->desktop()->width()*3/4 );
+ lay2->addWidget(recentFile);
+
+ QStringList fileList = KRecentDocument::recentDocuments();
+ QStringList lst;
+ lst <<"";
+ for (QStringList::ConstIterator it = fileList.begin();it != fileList.end(); ++it)
+ {
+ KDesktopFile f(*it, true /* read only */);
+ if ( !f.readURL().isEmpty())
+ lst.append( f.readURL());
+ }
+ if ( lst.count()<= 1 )
+ {
+ recentFile->clear();
+ recentFile->insertItem( i18n("No Entries") );
+ recentFile->setEnabled( false );
+ }
+ else
+ recentFile->insertStringList( lst);
+
+ recentFile->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed );
+
+ connect( recentFile , SIGNAL(highlighted ( const QString &)), this, SLOT( slotSelectRecentFile( const QString & )));
+
+ tmpQLabel = new QLabel( this);
+ lay2->addWidget(tmpQLabel);
+
+ tmpQLabel->setText(i18n("File location:"));
+ m_hrefName = new KURLRequester( this );
+
+ lay2->addWidget(m_hrefName);
+ lay2->addStretch( 1 );
+
+ connect(m_linkName,SIGNAL(textChanged ( const QString & )),this,SLOT(textChanged ( const QString & )));
+ connect(m_hrefName,SIGNAL(textChanged ( const QString & )),this,SLOT(textChanged ( const QString & )));
+
+ KSeparator* bar1 = new KSeparator( KSeparator::HLine, this);
+ bar1->setFixedHeight( 10 );
+ lay2->addWidget( bar1 );
+}
+
+void fileLinkPage::slotSelectRecentFile( const QString &_file )
+{
+ m_hrefName->lineEdit()->setText(_file );
+}
+
+QString fileLinkPage::createFileLink()
+{
+ QString result=m_hrefName->lineEdit()->text();
+ if(result.isEmpty())
+ return result;
+
+ if(result.find("file:/")==-1)
+ result = "file://"+result;
+ return result;
+}
+
+void fileLinkPage::setLinkName(const QString & _name)
+{
+ m_linkName->setText(_name);
+}
+
+void fileLinkPage::setHrefName(const QString &_name)
+{
+ m_hrefName->lineEdit()->setText(_name);
+}
+
+QString fileLinkPage::linkName()const
+{
+ return m_linkName->text();
+}
+
+QString fileLinkPage::hrefName()
+{
+ return createFileLink();
+}
+
+void fileLinkPage::textChanged ( const QString & )
+{
+ emit textChanged();
+}
+
+#include "KoInsertLink.moc"
diff --git a/lib/kofficeui/KoInsertLink.h b/lib/kofficeui/KoInsertLink.h
new file mode 100644
index 00000000..79d5eeca
--- /dev/null
+++ b/lib/kofficeui/KoInsertLink.h
@@ -0,0 +1,148 @@
+/* This file is part of the KDE project
+ Copyright (C) 2001 Montel Laurent <lmontel@mandrakesoft.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#ifndef __KoInsertLink__
+#define __KoInsertLink__
+
+#include <kdialogbase.h>
+#include <koffice_export.h>
+class QLineEdit;
+class KURLRequester;
+
+namespace KOfficePrivate {
+/**
+ * @internal
+ */
+class internetLinkPage : public QWidget
+{
+ Q_OBJECT
+public:
+ internetLinkPage( QWidget *parent = 0, char *name = 0 );
+ QString linkName()const;
+ QString hrefName();
+ void setLinkName(const QString & _name);
+ void setHrefName(const QString &_name);
+private:
+ QString createInternetLink();
+ QLineEdit* m_linkName, *m_hrefName;
+private slots:
+ void textChanged ( const QString & );
+signals:
+ void textChanged();
+};
+
+/**
+ * @internal
+ */
+class bookmarkLinkPage : public QWidget
+{
+ Q_OBJECT
+public:
+ bookmarkLinkPage( QWidget *parent = 0, char *name = 0 );
+ QString linkName()const;
+ QString hrefName();
+ void setLinkName(const QString & _name);
+ void setHrefName(const QString &_name);
+ void setBookmarkList(const QStringList &bkmlist);
+private:
+ QString createBookmarkLink();
+ QLineEdit* m_linkName;
+ QComboBox *m_hrefName;
+private slots:
+ void textChanged ( const QString & );
+signals:
+ void textChanged();
+};
+
+/**
+ * @internal
+ */
+class mailLinkPage : public QWidget
+{
+ Q_OBJECT
+public:
+ mailLinkPage( QWidget *parent = 0, char *name = 0 );
+ QString linkName()const;
+ QString hrefName();
+ void setLinkName(const QString & _name);
+ void setHrefName(const QString &_name);
+
+private slots:
+ void textChanged ( const QString & );
+private:
+ QString createMailLink();
+ QLineEdit* m_linkName, *m_hrefName;
+signals:
+ void textChanged();
+};
+
+/**
+ * @internal
+ */
+class fileLinkPage : public QWidget
+{
+ Q_OBJECT
+public:
+ fileLinkPage( QWidget *parent = 0, char *name = 0 );
+ QString linkName()const;
+ QString hrefName();
+ void setLinkName(const QString & _name);
+ void setHrefName(const QString &_name);
+
+private slots:
+ void textChanged ( const QString & );
+ void slotSelectRecentFile( const QString & );
+private:
+ QString createFileLink();
+ QLineEdit* m_linkName;
+ KURLRequester* m_hrefName;
+signals:
+ void textChanged();
+};
+}
+
+/**
+ * Dialog to insert links to various sources (file, Internet, mail and bookmarks).
+ */
+class KOFFICEUI_EXPORT KoInsertLinkDia : public KDialogBase
+{
+ Q_OBJECT
+public:
+ KoInsertLinkDia( QWidget *parent, const char *name = 0,bool displayBookmarkLink=true );
+ static bool createLinkDia(QString & linkName, QString & hrefName, const QStringList& bkmlist, bool displayBookmarkLink = true,
+ QWidget* parent = 0, const char* name = 0);
+
+ //internal
+ QString linkName() const;
+ QString hrefName() const;
+ void setHrefLinkName(const QString &_href, const QString &_link, const QStringList & bkmlist);
+protected slots:
+ virtual void slotOk();
+ void slotTextChanged ( );
+ void tabChanged(QWidget *);
+
+private:
+ KOfficePrivate::fileLinkPage *fileLink;
+ KOfficePrivate::mailLinkPage *mailLink;
+ KOfficePrivate::internetLinkPage *internetLink;
+ KOfficePrivate::bookmarkLinkPage *bookmarkLink;
+ QString currentText;
+};
+
+#endif
diff --git a/lib/kofficeui/KoKoolBar.cpp b/lib/kofficeui/KoKoolBar.cpp
new file mode 100644
index 00000000..9715ce5e
--- /dev/null
+++ b/lib/kofficeui/KoKoolBar.cpp
@@ -0,0 +1,489 @@
+/* This file is part of the KDE project
+ Copyright (C) 1998, 1999 Torben Weis <weis@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#include <KoKoolBar.h>
+#include <kiconloader.h>
+
+#include <qpainter.h>
+#include <qpushbutton.h>
+
+static int g_koKoolBarId = 0;
+
+KoKoolBar::KoKoolBar( QWidget *_parent, const char *_name ) :
+ QWidget( _parent, _name ), m_iActiveGroup( -1 )
+{
+ m_mapGroups.setAutoDelete( true );
+ m_pBox = new KoKoolBarBox( this );
+}
+
+int KoKoolBar::insertGroup( const QString& _text )
+{
+ KoKoolBarGroup *p = new KoKoolBarGroup( this, _text );
+ m_mapGroups.insert( p->id(), p );
+
+ if ( m_iActiveGroup == -1 )
+ setActiveGroup( p->id() );
+ else
+ resizeEvent( 0L );
+ return p->id();
+}
+
+int KoKoolBar::insertItem( int _grp, const QPixmap& _pix, const QString& _text,
+ QObject *_obj, const char *_slot )
+{
+ KoKoolBarGroup* g = m_mapGroups[ _grp ];
+ if ( !g )
+ return -1;
+ KoKoolBarItem *item = new KoKoolBarItem( g, _pix, _text );
+
+ if ( _obj != 0L && _slot != 0L )
+ connect( item, SIGNAL( pressed( int, int ) ), _obj, _slot );
+ g->append( item );
+
+ if ( g->id() == m_iActiveGroup )
+ m_pBox->update();
+
+ return item->id();
+}
+
+void KoKoolBar::removeGroup( int _grp )
+{
+ KoKoolBarGroup* g = m_mapGroups[ _grp ];
+ if ( !g )
+ return;
+
+ m_mapGroups.remove( _grp );
+
+ if ( _grp == m_iActiveGroup )
+ {
+ if ( m_mapGroups.count() == 0 )
+ {
+ m_iActiveGroup = -1;
+ m_pBox->setActiveGroup( 0L );
+ }
+ else
+ {
+ QIntDictIterator<KoKoolBarGroup> it( m_mapGroups );
+ g = it.current();
+ m_iActiveGroup = g->id();
+ m_pBox->setActiveGroup( g );
+ }
+ }
+
+ resizeEvent( 0L );
+}
+
+void KoKoolBar::removeItem( int _grp, int _id )
+{
+ KoKoolBarGroup* g = m_mapGroups[ _grp ];
+ if ( !g )
+ return;
+
+ g->remove( _id );
+
+ if ( g->id() == m_iActiveGroup )
+ m_pBox->update();
+}
+
+void KoKoolBar::renameItem( int _grp, int _id, const QString & _text )
+{
+ KoKoolBarGroup* g = m_mapGroups[ _grp ];
+ if ( !g )
+ return;
+
+ KoKoolBarItem * item = g->item( _id );
+ if ( !item )
+ return;
+
+ item->setText( _text );
+
+ if ( g->id() == m_iActiveGroup )
+ m_pBox->update();
+}
+
+void KoKoolBar::setActiveGroup( int _grp )
+{
+ KoKoolBarGroup* g = m_mapGroups[ _grp ];
+ if ( !g )
+ return;
+
+ m_iActiveGroup = g->id();
+ m_pBox->setActiveGroup( g );
+
+ resizeEvent( 0L );
+}
+
+void KoKoolBar::resizeEvent( QResizeEvent * ev )
+{
+ if ( m_iActiveGroup == -1 )
+ return;
+
+ int buttonheight = fontMetrics().height() + 4;
+
+ KoKoolBarGroup *g = m_mapGroups[ m_iActiveGroup ];
+ if ( !g )
+ return;
+
+ // Go behind g
+ QIntDictIterator<KoKoolBarGroup> it( m_mapGroups );
+ while( it.current() != g )
+ ++it;
+ // Position of g
+ QIntDictIterator<KoKoolBarGroup> pos = it;
+ ++it;
+
+ // How many left ?
+ int result = 0;
+ QIntDictIterator<KoKoolBarGroup> i = it;
+ while( i.current() )
+ {
+ ++result;
+ ++i;
+ }
+
+ int y = height() - buttonheight * result;
+ for( ; it.current(); ++it )
+ {
+ it.current()->button()->setGeometry( 0, y, width(), buttonheight );
+ it.current()->button()->show();
+ y += buttonheight;
+ }
+
+ int y2 = 0;
+ it.toFirst();
+ ++pos;
+ while( it.current() != pos.current() )
+ {
+ it.current()->button()->setGeometry( 0, y2, width(), buttonheight );
+ it.current()->button()->show();
+ ++it;
+ y2 += buttonheight;
+ }
+
+ if ( height() - y2 - result * buttonheight >= 0 )
+ {
+ m_pBox->show();
+ m_pBox->setGeometry( 0, y2, width(), height() - y2 - result * buttonheight );
+ if ( !ev ) // fake event
+ m_pBox->sizeChanged();
+ }
+ else
+ m_pBox->hide();
+
+}
+
+void KoKoolBar::enableItem( int _grp, int _id, bool _enable )
+{
+ KoKoolBarGroup* g = m_mapGroups[ _grp ];
+ if ( !g )
+ return;
+ KoKoolBarItem *item = g->item( _id );
+ if ( !item )
+ return;
+ item->setEnabled( _enable );
+}
+
+void KoKoolBar::enableGroup( int _grp, bool _enable )
+{
+ KoKoolBarGroup* g = m_mapGroups[ _grp ];
+ if ( !g )
+ return;
+ g->setEnabled( _enable );
+}
+
+KoKoolBarBox::KoKoolBarBox( KoKoolBar *_bar ) :
+ QFrame( _bar ), m_pBar( _bar ),
+ m_pButtonUp( 0L ), m_pButtonDown( 0L )
+{
+ m_iYOffset = 0;
+ m_iYIcon = 0;
+ m_pGroup = 0L;
+
+ setFrameShape( StyledPanel );
+ setFrameShadow( Sunken );
+ // setBackgroundMode( PaletteBase );
+ setBackgroundColor( colorGroup().background() );
+}
+
+void KoKoolBarBox::setActiveGroup( KoKoolBarGroup *_grp )
+{
+ m_pGroup = _grp;
+ m_iYOffset = 0;
+ m_iYIcon = 0;
+ update();
+}
+
+bool KoKoolBarBox::needsScrolling() const
+{
+ if ( m_pGroup == 0L )
+ return false;
+
+ return ( maxHeight() > height() );
+}
+
+void KoKoolBarBox::resizeEvent( QResizeEvent * )
+{
+ if ( needsScrolling() )
+ {
+ if ( m_pButtonUp == 0L )
+ {
+ m_pButtonUp = new QPushButton( this );
+ m_pButtonUp->setPixmap( QPixmap( UserIcon( "koKoolBarUp" ) ) );
+ connect( m_pButtonUp, SIGNAL( clicked() ), this, SLOT( scrollUp() ) );
+ }
+ if ( m_pButtonDown == 0L )
+ {
+ m_pButtonDown = new QPushButton( this );
+ m_pButtonDown->setPixmap( QPixmap( UserIcon( "koKoolBarDown" ) ) );
+ connect( m_pButtonDown, SIGNAL( clicked() ), this, SLOT( scrollDown() ) );
+ }
+ m_pButtonUp->show();
+ m_pButtonUp->raise();
+ m_pButtonDown->show();
+ m_pButtonDown->raise();
+ updateScrollButtons();
+ }
+ else
+ {
+ if ( m_pButtonUp )
+ m_pButtonUp->hide();
+ if ( m_pButtonDown )
+ m_pButtonDown->hide();
+ }
+}
+
+KoKoolBarItem* KoKoolBarBox::findByPos( int _abs_y ) const
+{
+ if ( m_pGroup == 0L )
+ return 0L;
+
+ int y = 0;
+
+ QIntDictIterator<KoKoolBarItem> it = m_pGroup->iterator();
+ for ( ; it.current(); ++it )
+ {
+ int dy = it.current()->height();
+ if ( y <= _abs_y && _abs_y <= y + dy )
+ return it.current();
+ y += dy;
+ }
+
+ return 0L;
+}
+
+int KoKoolBarBox::maxHeight() const
+{
+ int y = 0;
+
+ QIntDictIterator<KoKoolBarItem> it = m_pGroup->iterator();
+ for ( ; it.current(); ++it )
+ y += it.current()->height();
+
+ return y;
+}
+
+bool KoKoolBarBox::isAtTop() const
+{
+ return ( m_iYIcon == 0 );
+}
+
+bool KoKoolBarBox::isAtBottom() const
+{
+ if ( m_pGroup->items() == 0 )
+ return true;
+ int h = maxHeight();
+ if ( height() + m_iYOffset >= h )
+ return true;
+ if ( m_pGroup->items() - 1 == m_iYIcon )
+ return true;
+ return false;
+}
+
+void KoKoolBarBox::scrollUp()
+{
+ if ( isAtTop() )
+ return;
+
+ int y = 0;
+ int i = 0;
+ m_iYIcon--;
+
+ QIntDictIterator<KoKoolBarItem> it = m_pGroup->iterator();
+ for ( ; i < m_iYIcon && it.current(); ++it )
+ {
+ y += it.current()->height();
+ ++i;
+ }
+
+ int old = m_iYOffset;
+ m_iYOffset = y;
+
+ QWidget::scroll( 0, old - m_iYOffset, contentsRect() );
+ updateScrollButtons();
+}
+
+void KoKoolBarBox::scrollDown()
+{
+ if ( isAtBottom() )
+ return;
+
+ int y = 0;
+ int i = 0;
+ m_iYIcon++;
+
+ QIntDictIterator<KoKoolBarItem> it = m_pGroup->iterator();
+ for ( ; i < m_iYIcon && it.current(); ++it )
+ {
+ y += it.current()->height();
+ i++;
+ }
+ int h = maxHeight();
+ if ( y + height() > h ) // Don't go after last item
+ y = h - height();
+
+ int old = m_iYOffset;
+ m_iYOffset = y;
+
+ QWidget::scroll( 0, old - m_iYOffset, contentsRect() );
+ updateScrollButtons();
+}
+
+void KoKoolBarBox::updateScrollButtons()
+{
+ if ( isAtTop() )
+ m_pButtonUp->setEnabled( false );
+ else
+ m_pButtonUp->setEnabled( true );
+
+ if ( isAtBottom() )
+ m_pButtonDown->setEnabled( false );
+ else
+ m_pButtonDown->setEnabled( true );
+
+ const int bs = 14; // buttonSize
+ m_pButtonUp->setGeometry( width() - bs, height() - 2 * bs, bs, bs );
+ m_pButtonDown->setGeometry( width() - bs, height() - bs, bs, bs );
+}
+
+void KoKoolBarBox::drawContents( QPainter * painter )
+{
+ if ( m_pGroup == 0L )
+ return;
+
+ int y = -m_iYOffset;
+
+ QIntDictIterator<KoKoolBarItem> it = m_pGroup->iterator();
+ for ( ; it.current(); ++it )
+ {
+ if ( y + it.current()->height() >= 0 && y <= height() ) // visible ?
+ {
+ painter->drawPixmap( ( width() - it.current()->pixmap().width() ) / 2, y, it.current()->pixmap() );
+ if ( !it.current()->text().isEmpty() )
+ {
+ int y2 = y + it.current()->pixmap().height() + 2;
+ painter->drawText( ( width() - painter->fontMetrics().width( it.current()->text() ) ) / 2,
+ y2 + painter->fontMetrics().ascent(), it.current()->text() );
+ }
+ }
+
+ y += it.current()->height();
+ }
+}
+
+KoKoolBarGroup::KoKoolBarGroup( KoKoolBar *_bar, const QString& _text ) :
+ m_pBar( _bar )
+{
+ m_mapItems.setAutoDelete( true );
+
+ m_pButton = new QPushButton( _text, _bar );
+
+ m_bEnabled = true;
+
+ connect( m_pButton, SIGNAL( clicked() ), this, SLOT( pressed() ) );
+ m_id = g_koKoolBarId++;
+}
+
+KoKoolBarGroup::~KoKoolBarGroup()
+{
+ delete m_pButton;
+}
+
+void KoKoolBarGroup::remove( int _id )
+{
+ m_mapItems.remove( _id );
+}
+
+void KoKoolBarGroup::pressed()
+{
+ m_pBar->setActiveGroup( m_id );
+}
+
+KoKoolBarItem::KoKoolBarItem( KoKoolBarGroup *_grp, const QPixmap& _pix, const QString&_text )
+ : m_pGroup( _grp )
+{
+ m_pixmap = _pix;
+ m_strText = _text;
+ m_bEnabled = true;
+ m_id = g_koKoolBarId++;
+ calc( _grp->bar() );
+}
+
+void KoKoolBarItem::calc( QWidget *_widget )
+{
+ m_iHeight = pixmap().height() + 8;
+
+ if ( !m_strText.isEmpty() )
+ m_iHeight += _widget->fontMetrics().height() + 2;
+}
+
+void KoKoolBarItem::press()
+{
+ emit pressed();
+ emit pressed( m_pGroup->id(), m_id );
+}
+
+/*
+
+int main( int argc, char **argv )
+{
+ KApplication app( argc, argv );
+ KoKoolBar bar;
+ int file = bar.insertGroup("File");
+ QPixmap pix;
+ pix.load( "/opt/kde/share/icons/image.xpm" );
+ bar.insertItem( file, pix );
+ pix.load( "/opt/kde/share/icons/html.xpm" );
+ bar.insertItem( file, pix );
+ pix.load( "/opt/kde/share/icons/txt.xpm" );
+ bar.insertItem( file, pix );
+ pix.load( "/opt/kde/share/icons/kfm.xpm" );
+ bar.insertItem( file, pix );
+
+ bar.insertGroup("Edit");
+ bar.insertGroup("View");
+ bar.insertGroup("Layout");
+ bar.insertGroup("Help");
+ bar.setGeometry( 100, 100, 80, 300 );
+ bar.show();
+
+ app.exec();
+}
+*/
+
+#include <KoKoolBar.moc>
diff --git a/lib/kofficeui/KoKoolBar.h b/lib/kofficeui/KoKoolBar.h
new file mode 100644
index 00000000..5e6f91fc
--- /dev/null
+++ b/lib/kofficeui/KoKoolBar.h
@@ -0,0 +1,166 @@
+/*
+ This file is part of the KDE project
+ Copyright (C) 1998, 1999 Torben Weis <weis@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#ifndef __ko_koolbar_h__
+#define __ko_koolbar_h__
+
+#include <qframe.h>
+#include <qpixmap.h>
+#include <qintdict.h>
+#include <koffice_export.h>
+class QPushButton;
+class QPixmap;
+class KoKoolBar;
+class KoKoolBarGroup;
+
+class KoKoolBarItem : public QObject
+{
+private:
+ Q_OBJECT
+public:
+ KoKoolBarItem( KoKoolBarGroup *_grp, const QPixmap& _pix, const QString& _text = QString::null );
+
+ int id() const { return m_id; }
+ void press();
+ bool isEnabled() const { return m_bEnabled; }
+ void setEnabled( bool _e ) { m_bEnabled = _e; }
+
+ int height() const { return m_iHeight; }
+ QPixmap pixmap() const { return m_pixmap; }
+ void setText( const QString & text ) { m_strText = text; }
+ QString text() const { return m_strText; }
+
+signals:
+ void pressed( int _group, int _id );
+ void pressed();
+protected:
+ void calc( QWidget* );
+
+ int m_iHeight;
+ KoKoolBarGroup* m_pGroup;
+ QString m_strText;
+ QPixmap m_pixmap;
+ int m_id;
+ bool m_bEnabled;
+ class KoKoolBarItemPrivate;
+ KoKoolBarItemPrivate *d;
+};
+
+class KoKoolBarGroup : public QObject
+{
+ Q_OBJECT
+public:
+ KoKoolBarGroup( KoKoolBar *_bar, const QString& _text );
+ ~KoKoolBarGroup();
+
+ void append( KoKoolBarItem *_i ) { m_mapItems.insert( _i->id(), _i ); }
+ void remove( int _id );
+
+ KoKoolBar* bar() const { return m_pBar; }
+ QPushButton* button() const { return m_pButton; }
+ int id() const { return m_id; }
+ bool isEnabled() const { return m_bEnabled; }
+ void setEnabled( bool _e ) { m_bEnabled = _e; }
+ KoKoolBarItem* item( int _id ) const { return m_mapItems[ _id ]; }
+ int items() const { return m_mapItems.size(); }
+ QIntDictIterator<KoKoolBarItem> iterator() const { return QIntDictIterator<KoKoolBarItem>( m_mapItems ); }
+
+public slots:
+ void pressed();
+
+protected:
+ QIntDict<KoKoolBarItem> m_mapItems;
+ KoKoolBar* m_pBar;
+ QString m_strText;
+ int m_id;
+ QPushButton* m_pButton;
+ bool m_bEnabled;
+ class KoKoolBarGroupPrivate;
+ KoKoolBarGroupPrivate *d;
+};
+
+class KoKoolBarBox : public QFrame
+{
+ Q_OBJECT
+public:
+ KoKoolBarBox( KoKoolBar *_bar );
+
+ void setActiveGroup( KoKoolBarGroup *_grp );
+ int maxHeight() const;
+
+ void sizeChanged() { resizeEvent(0L); }
+
+protected slots:
+ void scrollUp();
+ void scrollDown();
+
+protected:
+ virtual void resizeEvent( QResizeEvent *_ev );
+ virtual void drawContents( QPainter * );
+ virtual void mousePressEvent( QMouseEvent *_ev )
+ { KoKoolBarItem *item = findByPos( _ev->pos().y() + m_iYOffset ); if ( !item ) return; item->press(); }
+
+ KoKoolBarItem* findByPos( int _abs_y ) const;
+
+ bool needsScrolling() const;
+ bool isAtBottom() const;
+ bool isAtTop() const;
+ void updateScrollButtons();
+
+ KoKoolBar *m_pBar;
+ int m_iYOffset;
+ int m_iYIcon;
+ KoKoolBarGroup *m_pGroup;
+ QPushButton* m_pButtonUp;
+ QPushButton* m_pButtonDown;
+ class KoKoolBarBoxPrivate;
+ KoKoolBarBoxPrivate *d;
+};
+
+class KOFFICEUI_EXPORT KoKoolBar : public QWidget
+{
+ Q_OBJECT
+public:
+ KoKoolBar( QWidget *_parent = 0L, const char *_name = 0L );
+ virtual ~KoKoolBar() { };
+
+ virtual int insertGroup( const QString& _text );
+ virtual int insertItem( int _grp, const QPixmap& _pix, const QString& _text = QString::null,
+ QObject *_obj = 0L, const char *_slot = 0L );
+ virtual void removeGroup( int _grp );
+ virtual void removeItem( int _grp, int _id );
+ virtual void renameItem( int _grp, int _id, const QString & _text );
+ virtual void setActiveGroup( int _grp );
+ virtual int activeGroup() const { return m_iActiveGroup; }
+ virtual void enableItem( int _grp, int _id, bool _enable );
+ virtual void enableGroup( int _grp, bool _enable );
+
+protected:
+ virtual void resizeEvent( QResizeEvent *_ev );
+
+ QIntDict<KoKoolBarGroup> m_mapGroups;
+
+ int m_iActiveGroup;
+ KoKoolBarBox* m_pBox;
+ class KoKoolBarPrivate;
+ KoKoolBarPrivate *d;
+};
+
+#endif
diff --git a/lib/kofficeui/KoPageLayoutColumns.cpp b/lib/kofficeui/KoPageLayoutColumns.cpp
new file mode 100644
index 00000000..db5e3e25
--- /dev/null
+++ b/lib/kofficeui/KoPageLayoutColumns.cpp
@@ -0,0 +1,70 @@
+/* This file is part of the KDE project
+ * Copyright (C) 1998, 1999 Reginald Stadlbauer <reggie@kde.org>
+ * Copyright (C) 2005 Thomas Zander <zander@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; version 2.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <KoPageLayoutColumns.h>
+#include <KoPageLayoutDia.h>
+#include <KoUnit.h>
+#include <KoUnitWidgets.h>
+
+#include <qlabel.h>
+#include <qlayout.h>
+
+KoPageLayoutColumns::KoPageLayoutColumns(QWidget *parent, const KoColumns& columns, KoUnit::Unit unit, const KoPageLayout& layout)
+ : KoPageLayoutColumnsBase(parent) {
+ m_columns = columns;
+ QHBoxLayout *lay = new QHBoxLayout(previewPane);
+ m_preview = new KoPagePreview( previewPane, "Preview", layout );
+ lay->addWidget(m_preview);
+ lay = new QHBoxLayout(columnSpacingPane);
+ m_spacing = new KoUnitDoubleSpinBox( columnSpacingPane );
+ m_spacing->setValue( m_columns.ptColumnSpacing );
+ m_spacing->setUnit( unit );
+ double dStep = KoUnit::fromUserValue( 0.2, unit );
+ m_spacing->setMinMaxStep( 0, layout.ptWidth/2, dStep );
+ lay->addWidget(m_spacing);
+ labelSpacing->setBuddy( m_spacing );
+ nColumns->setValue( m_columns.columns );
+ m_preview->setPageColumns( m_columns );
+
+ connect( nColumns, SIGNAL( valueChanged( int ) ), this, SLOT( nColChanged( int ) ) );
+ connect( m_spacing, SIGNAL( valueChangedPt(double) ), this, SLOT( nSpaceChanged( double ) ) );
+}
+
+void KoPageLayoutColumns::setEnableColumns(bool on) {
+ nColumns->setEnabled(on);
+ m_spacing->setEnabled(on);
+ nColChanged(on ? nColumns->value(): 1 );
+}
+
+void KoPageLayoutColumns::nColChanged( int columns ) {
+ m_columns.columns = columns;
+ m_preview->setPageColumns( m_columns );
+ emit propertyChange(m_columns);
+}
+
+void KoPageLayoutColumns::nSpaceChanged( double spacing ) {
+ m_columns.ptColumnSpacing = spacing;
+ emit propertyChange(m_columns);
+}
+
+void KoPageLayoutColumns::setLayout(KoPageLayout &layout) {
+ m_preview->setPageLayout( layout );
+}
+
+#include <KoPageLayoutColumns.moc>
diff --git a/lib/kofficeui/KoPageLayoutColumns.h b/lib/kofficeui/KoPageLayoutColumns.h
new file mode 100644
index 00000000..be0a4a49
--- /dev/null
+++ b/lib/kofficeui/KoPageLayoutColumns.h
@@ -0,0 +1,75 @@
+/* This file is part of the KDE project
+ * Copyright (C) 1998, 1999 Reginald Stadlbauer <reggie@kde.org>
+ * Copyright (C) 2005 Thomas Zander <zander@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; version 2.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// Description: Page Layout Dialog (sources)
+
+#ifndef kopagelayoutcolumns_h
+#define kopagelayoutcolumns_h
+
+#include <KoUnit.h>
+#include <KoPageLayout.h>
+#include <KoPageLayoutColumnsBase.h>
+
+class QWidget;
+class KoUnitDoubleSpinBox;
+class KoPagePreview;
+
+/**
+ * This class is a widget that shows the KoColumns data structure and allows the user to change it.
+ */
+class KoPageLayoutColumns : public KoPageLayoutColumnsBase {
+ Q_OBJECT
+
+public:
+ /**
+ * Contructor
+ * @param parent the parent widget
+ * @param columns the KoColumns data structure that this dialog should be initialzed with
+ * @param unit the unit-type (mm/cm/inch) that the dialog should show
+ * @param layout the page layout that the preview should be initialzed with.
+ */
+ KoPageLayoutColumns(QWidget *parent, const KoColumns& columns, KoUnit::Unit unit, const KoPageLayout& layout);
+
+ /**
+ * Update the page preview widget with the param layout.
+ * @param layout the new layout
+ */
+ void setLayout(KoPageLayout &layout);
+public slots:
+
+ /**
+ * Enable the user to edit the columns
+ * @param on if true enable the user to change the columns count
+ */
+ void setEnableColumns(bool on);
+
+signals:
+ void propertyChange(KoColumns &columns);
+
+protected:
+ KoColumns m_columns;
+ KoPagePreview *m_preview;
+ KoUnitDoubleSpinBox *m_spacing;
+
+private slots:
+ void nColChanged( int );
+ void nSpaceChanged( double );
+};
+
+#endif
diff --git a/lib/kofficeui/KoPageLayoutColumnsBase.ui b/lib/kofficeui/KoPageLayoutColumnsBase.ui
new file mode 100644
index 00000000..1ffe032d
--- /dev/null
+++ b/lib/kofficeui/KoPageLayoutColumnsBase.ui
@@ -0,0 +1,99 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>KoPageLayoutColumnsBase</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>KoPageLayoutColumnsBase</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>361</width>
+ <height>169</height>
+ </rect>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QFrame" row="1" column="1">
+ <property name="name">
+ <cstring>columnSpacingPane</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Raised</enum>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>Columns:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>nColumns</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>labelSpacing</cstring>
+ </property>
+ <property name="text">
+ <string>Column spacing:</string>
+ </property>
+ </widget>
+ <spacer row="2" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QFrame" row="0" column="2" rowspan="3" colspan="1">
+ <property name="name">
+ <cstring>previewPane</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>7</vsizetype>
+ <horstretch>1</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape">
+ <enum>NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Raised</enum>
+ </property>
+ </widget>
+ <widget class="QSpinBox" row="0" column="1">
+ <property name="name">
+ <cstring>nColumns</cstring>
+ </property>
+ <property name="maxValue">
+ <number>16</number>
+ </property>
+ <property name="minValue">
+ <number>1</number>
+ </property>
+ </widget>
+ </grid>
+</widget>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/lib/kofficeui/KoPageLayoutDia.cpp b/lib/kofficeui/KoPageLayoutDia.cpp
new file mode 100644
index 00000000..13194df1
--- /dev/null
+++ b/lib/kofficeui/KoPageLayoutDia.cpp
@@ -0,0 +1,402 @@
+/* This file is part of the KDE project
+ Copyright (C) 1998, 1999 Reginald Stadlbauer <reggie@kde.org>
+ Copyright (C) 2005 Thomas Zander <zander@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+// Description: Page Layout Dialog (sources)
+
+/******************************************************************/
+
+#include <KoPageLayoutDia.h>
+#include <KoPageLayoutColumns.h>
+#include <KoPageLayoutSize.h>
+#include <KoPageLayoutHeader.h>
+#include <KoUnit.h>
+#include <KoUnitWidgets.h>
+
+#include <klocale.h>
+#include <kiconloader.h>
+#include <kmessagebox.h>
+
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qpainter.h>
+#include <qlineedit.h>
+#include <qbuttongroup.h>
+#include <qradiobutton.h>
+#include <qcheckbox.h>
+#include <qhbox.h>
+#include <qvgroupbox.h>
+#include <qhbuttongroup.h>
+
+/******************************************************************/
+/* class KoPagePreview */
+/******************************************************************/
+
+/*===================== constrcutor ==============================*/
+KoPagePreview::KoPagePreview( QWidget* parent, const char *name, const KoPageLayout& layout )
+ : QGroupBox( i18n( "Page Preview" ), parent, name )
+{
+ setPageLayout( layout );
+ columns = 1;
+ setMinimumSize( 150, 150 );
+}
+
+/*====================== destructor ==============================*/
+KoPagePreview::~KoPagePreview()
+{
+}
+
+/*=================== set layout =================================*/
+void KoPagePreview::setPageLayout( const KoPageLayout &layout )
+{
+ // resolution[XY] is in pixel per pt
+ double resolutionX = POINT_TO_INCH( static_cast<double>(KoGlobal::dpiX()) );
+ double resolutionY = POINT_TO_INCH( static_cast<double>(KoGlobal::dpiY()) );
+
+ m_pageWidth = layout.ptWidth * resolutionX;
+ m_pageHeight = layout.ptHeight * resolutionY;
+
+ double zh = 110.0 / m_pageHeight;
+ double zw = 110.0 / m_pageWidth;
+ double z = QMIN( zw, zh );
+
+ m_pageWidth *= z;
+ m_pageHeight *= z;
+
+ m_textFrameX = layout.ptLeft * resolutionX * z;
+ m_textFrameY = layout.ptTop * resolutionY * z;
+ m_textFrameWidth = m_pageWidth - ( layout.ptLeft + layout.ptRight ) * resolutionX * z;
+ m_textFrameHeight = m_pageHeight - ( layout.ptTop + layout.ptBottom ) * resolutionY * z;
+
+ repaint( true );
+}
+
+/*=================== set layout =================================*/
+void KoPagePreview::setPageColumns( const KoColumns &_columns )
+{
+ columns = _columns.columns;
+ repaint( true );
+}
+
+/*======================== draw contents =========================*/
+void KoPagePreview::drawContents( QPainter *painter )
+{
+ double cw = m_textFrameWidth;
+ if(columns!=1)
+ cw/=static_cast<double>(columns);
+
+ painter->setBrush( white );
+ painter->setPen( QPen( black ) );
+
+ int x=static_cast<int>( ( width() - m_pageWidth ) * 0.5 );
+ int y=static_cast<int>( ( height() - m_pageHeight ) * 0.5 );
+ int w=static_cast<int>(m_pageWidth);
+ int h=static_cast<int>(m_pageHeight);
+ //painter->drawRect( x + 1, y + 1, w, h);
+ painter->drawRect( x, y, w, h );
+
+ painter->setBrush( QBrush( black, HorPattern ) );
+ if ( m_textFrameWidth == m_pageWidth || m_textFrameHeight == m_pageHeight )
+ painter->setPen( NoPen );
+ else
+ painter->setPen( lightGray );
+
+ for ( int i = 0; i < columns; ++i )
+ painter->drawRect( x + static_cast<int>(m_textFrameX) + static_cast<int>(i * cw),
+ y + static_cast<int>(m_textFrameY), static_cast<int>(cw),
+ static_cast<int>(m_textFrameHeight) );
+}
+
+/******************************************************************/
+/* class KoPageLayoutDia */
+/******************************************************************/
+
+/*==================== constructor ===============================*/
+KoPageLayoutDia::KoPageLayoutDia( QWidget* parent, const char* name,
+ const KoPageLayout& layout,
+ const KoHeadFoot& hf, int tabs,
+ KoUnit::Unit unit, bool modal )
+ : KDialogBase( KDialogBase::Tabbed, i18n("Page Layout"), KDialogBase::Ok | KDialogBase::Cancel,
+ KDialogBase::Ok, parent, name, modal)
+{
+
+ flags = tabs;
+ m_layout = layout;
+ m_unit = unit;
+ m_pageSizeTab = 0;
+ m_columnsTab = 0;
+ m_headerTab = 0;
+
+ m_column.columns = 1;
+
+ if ( tabs & FORMAT_AND_BORDERS ) setupTab1( true );
+ if ( tabs & HEADER_AND_FOOTER ) setupTab2( hf );
+
+ setFocusPolicy( QWidget::StrongFocus );
+ setFocus();
+}
+
+/*==================== constructor ===============================*/
+KoPageLayoutDia::KoPageLayoutDia( QWidget* parent, const char* name,
+ const KoPageLayout& layout,
+ const KoHeadFoot& hf,
+ const KoColumns& columns,
+ const KoKWHeaderFooter& kwhf,
+ int tabs, KoUnit::Unit unit )
+ : KDialogBase( KDialogBase::Tabbed, i18n("Page Layout"), KDialogBase::Ok | KDialogBase::Cancel,
+ KDialogBase::Ok, parent, name, true)
+{
+ flags = tabs;
+
+ m_layout = layout;
+ m_column = columns;
+ m_unit = unit;
+ m_pageSizeTab = 0;
+ m_columnsTab = 0;
+ m_headerTab = 0;
+
+ if ( tabs & FORMAT_AND_BORDERS ) setupTab1( !( tabs & DISABLE_BORDERS ) );
+ if ( tabs & HEADER_AND_FOOTER ) setupTab2( hf );
+ if ( tabs & COLUMNS ) setupTab3();
+ if ( tabs & KW_HEADER_AND_FOOTER ) setupTab4(kwhf);
+
+ setFocusPolicy( QWidget::StrongFocus );
+ setFocus();
+}
+
+/*===================== destructor ===============================*/
+KoPageLayoutDia::~KoPageLayoutDia()
+{
+}
+
+/*======================= show dialog ============================*/
+bool KoPageLayoutDia::pageLayout( KoPageLayout& layout, KoHeadFoot& hf, int tabs, KoUnit::Unit& unit, QWidget* parent )
+{
+ bool res = false;
+ KoPageLayoutDia *dlg = new KoPageLayoutDia( parent, "PageLayout", layout, hf, tabs, unit );
+
+ if ( dlg->exec() == QDialog::Accepted ) {
+ res = true;
+ if ( tabs & FORMAT_AND_BORDERS ) layout = dlg->layout();
+ if ( tabs & HEADER_AND_FOOTER ) hf = dlg->headFoot();
+ unit = dlg->unit();
+ }
+
+ delete dlg;
+
+ return res;
+}
+
+/*======================= show dialog ============================*/
+bool KoPageLayoutDia::pageLayout( KoPageLayout& layout, KoHeadFoot& hf, KoColumns& columns,
+ KoKWHeaderFooter &_kwhf, int tabs, KoUnit::Unit& unit, QWidget* parent )
+{
+ bool res = false;
+ KoPageLayoutDia *dlg = new KoPageLayoutDia( parent, "PageLayout", layout, hf, columns, _kwhf, tabs, unit );
+
+ if ( dlg->exec() == QDialog::Accepted ) {
+ res = true;
+ if ( tabs & FORMAT_AND_BORDERS ) layout = dlg->layout();
+ if ( tabs & HEADER_AND_FOOTER ) hf = dlg->headFoot();
+ if ( tabs & COLUMNS ) columns = dlg->columns();
+ if ( tabs & KW_HEADER_AND_FOOTER ) _kwhf = dlg->headerFooter();
+ unit = dlg->unit();
+ }
+
+ delete dlg;
+
+ return res;
+}
+
+/*===================== get a standard page layout ===============*/
+KoPageLayout KoPageLayoutDia::standardLayout()
+{
+ return KoPageLayout::standardLayout();
+}
+
+/*====================== get header - footer =====================*/
+KoHeadFoot KoPageLayoutDia::headFoot() const
+{
+ KoHeadFoot hf;
+ hf.headLeft = eHeadLeft->text();
+ hf.headMid = eHeadMid->text();
+ hf.headRight = eHeadRight->text();
+ hf.footLeft = eFootLeft->text();
+ hf.footMid = eFootMid->text();
+ hf.footRight = eFootRight->text();
+ return hf;
+}
+
+/*================================================================*/
+const KoKWHeaderFooter& KoPageLayoutDia::headerFooter()
+{
+ return m_headerTab->headerFooter();
+}
+
+/*================ setup page size & margins tab ==================*/
+void KoPageLayoutDia::setupTab1( bool enableBorders )
+{
+ QWidget *tab1 = addPage(i18n( "Page Size && &Margins" ));
+ QHBoxLayout *lay = new QHBoxLayout(tab1);
+ m_pageSizeTab = new KoPageLayoutSize(tab1, m_layout, m_unit, m_column, !(flags & DISABLE_UNIT), enableBorders );
+ lay->addWidget(m_pageSizeTab);
+ m_pageSizeTab->show();
+ connect (m_pageSizeTab, SIGNAL( propertyChange(KoPageLayout&)),
+ this, SLOT (sizeUpdated( KoPageLayout&)));
+}
+
+void KoPageLayoutDia::sizeUpdated(KoPageLayout &layout) {
+ m_layout.ptWidth = layout.ptWidth;
+ m_layout.ptHeight = layout.ptHeight;
+ m_layout.ptLeft = layout.ptLeft;
+ m_layout.ptRight = layout.ptRight;
+ m_layout.ptTop = layout.ptTop;
+ m_layout.ptBottom = layout.ptBottom;
+ m_layout.format = layout.format;
+ m_layout.orientation = layout.orientation;
+ if(m_columnsTab)
+ m_columnsTab->setLayout(layout);
+}
+
+/*================ setup header and footer tab ===================*/
+void KoPageLayoutDia::setupTab2( const KoHeadFoot& hf )
+{
+ QWidget *tab2 = addPage(i18n( "H&eader && Footer" ));
+ QGridLayout *grid2 = new QGridLayout( tab2, 7, 2, 0, KDialog::spacingHint() );
+
+ // ------------- header ---------------
+ QGroupBox *gHead = new QGroupBox( 0, Qt::Vertical, i18n( "Head Line" ), tab2 );
+ gHead->layout()->setSpacing(KDialog::spacingHint());
+ gHead->layout()->setMargin(KDialog::marginHint());
+ QGridLayout *headGrid = new QGridLayout( gHead->layout(), 2, 3 );
+
+ QLabel *lHeadLeft = new QLabel( i18n( "Left:" ), gHead );
+ headGrid->addWidget( lHeadLeft, 0, 0 );
+
+ eHeadLeft = new QLineEdit( gHead );
+ headGrid->addWidget( eHeadLeft, 1, 0 );
+ eHeadLeft->setText( hf.headLeft );
+
+ QLabel *lHeadMid = new QLabel( i18n( "Mid:" ), gHead );
+ headGrid->addWidget( lHeadMid, 0, 1 );
+
+ eHeadMid = new QLineEdit( gHead );
+ headGrid->addWidget( eHeadMid, 1, 1 );
+ eHeadMid->setText( hf.headMid );
+
+ QLabel *lHeadRight = new QLabel( i18n( "Right:" ), gHead );
+ headGrid->addWidget( lHeadRight, 0, 2 );
+
+ eHeadRight = new QLineEdit( gHead );
+ headGrid->addWidget( eHeadRight, 1, 2 );
+ eHeadRight->setText( hf.headRight );
+
+ grid2->addMultiCellWidget( gHead, 0, 1, 0, 1 );
+
+ // ------------- footer ---------------
+ QGroupBox *gFoot = new QGroupBox( 0, Qt::Vertical, i18n( "Foot Line" ), tab2 );
+ gFoot->layout()->setSpacing(KDialog::spacingHint());
+ gFoot->layout()->setMargin(KDialog::marginHint());
+ QGridLayout *footGrid = new QGridLayout( gFoot->layout(), 2, 3 );
+
+ QLabel *lFootLeft = new QLabel( i18n( "Left:" ), gFoot );
+ footGrid->addWidget( lFootLeft, 0, 0 );
+
+ eFootLeft = new QLineEdit( gFoot );
+ footGrid->addWidget( eFootLeft, 1, 0 );
+ eFootLeft->setText( hf.footLeft );
+
+ QLabel *lFootMid = new QLabel( i18n( "Mid:" ), gFoot );
+ footGrid->addWidget( lFootMid, 0, 1 );
+
+ eFootMid = new QLineEdit( gFoot );
+ footGrid->addWidget( eFootMid, 1, 1 );
+ eFootMid->setText( hf.footMid );
+
+ QLabel *lFootRight = new QLabel( i18n( "Right:" ), gFoot );
+ footGrid->addWidget( lFootRight, 0, 2 );
+
+ eFootRight = new QLineEdit( gFoot );
+ footGrid->addWidget( eFootRight, 1, 2 );
+ eFootRight->setText( hf.footRight );
+
+ grid2->addMultiCellWidget( gFoot, 2, 3, 0, 1 );
+
+ QLabel *lMacros2 = new QLabel( i18n( "You can insert several tags in the text:" ), tab2 );
+ grid2->addMultiCellWidget( lMacros2, 4, 4, 0, 1 );
+
+ QLabel *lMacros3 = new QLabel( i18n("<qt><ul><li>&lt;sheet&gt; The sheet name</li>"
+ "<li>&lt;page&gt; The current page</li>"
+ "<li>&lt;pages&gt; The total number of pages</li>"
+ "<li>&lt;name&gt; The filename or URL</li>"
+ "<li>&lt;file&gt; The filename with complete path or the URL</li></ul></qt>"), tab2 );
+ grid2->addMultiCellWidget( lMacros3, 5, 6, 0, 0, Qt::AlignTop );
+
+ QLabel *lMacros4 = new QLabel( i18n("<qt><ul><li>&lt;time&gt; The current time</li>"
+ "<li>&lt;date&gt; The current date</li>"
+ "<li>&lt;author&gt; Your full name</li>"
+ "<li>&lt;org&gt; Your organization</li>"
+ "<li>&lt;email&gt; Your email address</li></ul></qt>"), tab2 );
+ grid2->addMultiCellWidget( lMacros4, 5, 6, 1, 1, Qt::AlignTop );
+}
+
+/*================================================================*/
+void KoPageLayoutDia::setupTab3()
+{
+ QWidget *tab3 = addPage(i18n( "Col&umns" ));
+ QHBoxLayout *lay = new QHBoxLayout(tab3);
+ m_columnsTab = new KoPageLayoutColumns(tab3, m_column, m_unit, m_layout);
+ m_columnsTab->layout()->setMargin(0);
+ lay->addWidget(m_columnsTab);
+ m_columnsTab->show();
+ connect (m_columnsTab, SIGNAL( propertyChange(KoColumns&)),
+ this, SLOT (columnsUpdated( KoColumns&)));
+}
+
+void KoPageLayoutDia::columnsUpdated(KoColumns &columns) {
+ m_column.columns = columns.columns;
+ m_column.ptColumnSpacing = columns.ptColumnSpacing;
+ if(m_pageSizeTab)
+ m_pageSizeTab->setColumns(columns);
+}
+
+/*================================================================*/
+void KoPageLayoutDia::setupTab4(const KoKWHeaderFooter kwhf )
+{
+ QWidget *tab4 = addPage(i18n( "H&eader && Footer" ));
+ QHBoxLayout *lay = new QHBoxLayout(tab4);
+ m_headerTab = new KoPageLayoutHeader(tab4, m_unit, kwhf);
+ m_headerTab->layout()->setMargin(0);
+ lay->addWidget(m_headerTab);
+ m_headerTab->show();
+
+}
+
+
+/* Validation when closing. Error messages are never liked, but
+ better let the users enter all values in any order, and have one
+ final validation, than preventing them from entering values. */
+void KoPageLayoutDia::slotOk()
+{
+ if( m_pageSizeTab )
+ m_pageSizeTab->queryClose();
+ KDialogBase::slotOk(); // accept
+}
+
+#include <KoPageLayoutDia.moc>
diff --git a/lib/kofficeui/KoPageLayoutDia.h b/lib/kofficeui/KoPageLayoutDia.h
new file mode 100644
index 00000000..f3f1d932
--- /dev/null
+++ b/lib/kofficeui/KoPageLayoutDia.h
@@ -0,0 +1,200 @@
+/* This file is part of the KDE project
+ Copyright (C) 1998, 1999 Reginald Stadlbauer <reggie@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+// Description: Page Layout Dialog (header)
+
+#ifndef __KOPGLAYOUTDIA_H__
+#define __KOPGLAYOUTDIA_H__
+
+#include <qgroupbox.h>
+#include <KoGlobal.h>
+#include <KoUnit.h>
+#include <kdialogbase.h>
+#include <KoPageLayout.h>
+
+class QButtonGroup;
+class QComboBox;
+class QLineEdit;
+class QCheckBox;
+class KoUnitDoubleSpinBox;
+class KoPageLayoutColumns;
+class KoPageLayoutSize;
+class KoPageLayoutHeader;
+
+enum { FORMAT_AND_BORDERS = 1, HEADER_AND_FOOTER = 2, COLUMNS = 4, DISABLE_BORDERS = 8,
+ KW_HEADER_AND_FOOTER = 16, DISABLE_UNIT = 32 };
+
+/**
+ * KoPagePreview.
+ * Internal to KoPageLayoutDia.
+ */
+class KoPagePreview : public QGroupBox
+{
+ Q_OBJECT
+
+public:
+
+ /**
+ * constructor
+ */
+ KoPagePreview( QWidget*, const char*, const KoPageLayout & );
+ /**
+ * destructor
+ */
+ ~KoPagePreview();
+
+ /**
+ * set page layout
+ */
+ void setPageLayout( const KoPageLayout& );
+ void setPageColumns( const KoColumns& );
+
+protected:
+
+ // paint page
+ void drawContents( QPainter* );
+
+ double m_pageHeight, m_pageWidth, m_textFrameX, m_textFrameY, m_textFrameWidth, m_textFrameHeight;
+ int columns;
+};
+
+class KoPageLayoutDiaPrivate;
+
+/**
+ * With this dialog the user can specify the layout of the paper during printing.
+ */
+class KOFFICEUI_EXPORT KoPageLayoutDia : public KDialogBase
+{
+ Q_OBJECT
+
+public:
+
+ /**
+ * Constructor.
+ *
+ * @param parent The parent of the dialog.
+ * @param name The name of the dialog.
+ * @param layout The layout.
+ * @param headfoot The header and the footer.
+ * @param flags a variable with all features this dialog should show.
+ * @param unit The unit to use for displaying the values to the user.
+ * @param modal Whether the dialog is modal or not.
+ */
+ KoPageLayoutDia( QWidget* parent, const char* name,
+ const KoPageLayout& layout,
+ const KoHeadFoot& headfoot,
+ int flags, KoUnit::Unit unit, bool modal=true );
+
+ /**
+ * Constructor.
+ *
+ * @param parent The parent of the dialog.
+ * @param name The name of the dialog.
+ * @param layout The layout.
+ * @param headfoot The header and the footer.
+ * @param columns The number of columns on the page.
+ * @param kwheadfoot The KWord header and footer.
+ * @param tabs The number of tabs.
+ * @param unit The unit to use for displaying the values to the user
+ */
+ KoPageLayoutDia( QWidget* parent, const char* name,
+ const KoPageLayout& layout,
+ const KoHeadFoot& headfoot,
+ const KoColumns& columns,
+ const KoKWHeaderFooter& kwheadfoot,
+ int tabs, KoUnit::Unit unit );
+
+ /**
+ * Destructor.
+ */
+ ~KoPageLayoutDia();
+
+ /**
+ * Show page layout dialog.
+ * See constructor for documentation on the parameters
+ */
+ static bool pageLayout( KoPageLayout&, KoHeadFoot&, int tabs, KoUnit::Unit& unit, QWidget* parent = 0 );
+
+ /**
+ * Show page layout dialog.
+ * See constructor for documentation on the parameters
+ */
+ static bool pageLayout( KoPageLayout&, KoHeadFoot&, KoColumns&, KoKWHeaderFooter&, int tabs, KoUnit::Unit& unit, QWidget* parent = 0 );
+ /**
+ * Retrieves a standard page layout.
+ * Deprecated: better use KoPageLayout::standardLayout()
+ */
+ static KDE_DEPRECATED KoPageLayout standardLayout();
+
+ /**
+ * Returns the layout
+ */
+ const KoPageLayout& layout() const { return m_layout; }
+
+ /**
+ * Returns the header and footer information
+ */
+ KoHeadFoot headFoot() const;
+
+ /**
+ * Returns the unit
+ */
+ KoUnit::Unit unit() const { return m_unit; }
+
+private:
+ const KoColumns& columns() { return m_column; }
+ const KoKWHeaderFooter& headerFooter();
+
+ // setup tabs
+ void setupTab1( bool enableBorders );
+ void setupTab2( const KoHeadFoot& hf );
+ void setupTab3();
+ void setupTab4( const KoKWHeaderFooter kwhf );
+
+ // dialog objects
+ QLineEdit *eHeadLeft;
+ QLineEdit *eHeadMid;
+ QLineEdit *eHeadRight;
+ QLineEdit *eFootLeft;
+ QLineEdit *eFootMid;
+ QLineEdit *eFootRight;
+
+ // layout
+ KoPageLayout m_layout;
+ KoColumns m_column;
+
+ KoUnit::Unit m_unit;
+
+ int flags;
+
+protected slots:
+ virtual void slotOk();
+
+private slots:
+ void sizeUpdated(KoPageLayout &layout);
+ void columnsUpdated(KoColumns &columns);
+
+private:
+ KoPageLayoutSize *m_pageSizeTab;
+ KoPageLayoutColumns *m_columnsTab;
+ KoPageLayoutHeader *m_headerTab;
+ KoPageLayoutDiaPrivate *d;
+};
+
+#endif
diff --git a/lib/kofficeui/KoPageLayoutHeader.cpp b/lib/kofficeui/KoPageLayoutHeader.cpp
new file mode 100644
index 00000000..ad5e018c
--- /dev/null
+++ b/lib/kofficeui/KoPageLayoutHeader.cpp
@@ -0,0 +1,73 @@
+/* This file is part of the KDE project
+ * Copyright (C) 2005 Thomas Zander <zander@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; version 2.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <KoPageLayoutHeader.h>
+#include <KoPageLayoutHeader.moc>
+#include <KoUnitWidgets.h>
+
+#include <qlayout.h>
+#include <qcheckbox.h>
+
+KoPageLayoutHeader::KoPageLayoutHeader(QWidget *parent, KoUnit::Unit unit, const KoKWHeaderFooter &kwhf)
+ : KoPageLayoutHeaderBase(parent) {
+ m_headerFooters = kwhf;
+ QHBoxLayout *lay = new QHBoxLayout(headerSpacingPane);
+ m_headerSpacing = new KoUnitDoubleSpinBox( headerSpacingPane, 0.0, 999.0, 0.5, kwhf.ptHeaderBodySpacing, unit );
+ lay->addWidget(m_headerSpacing);
+
+ lay = new QHBoxLayout(footerSpacingPane);
+ m_footerSpacing = new KoUnitDoubleSpinBox( footerSpacingPane, 0.0, 999.0, 0.5, kwhf.ptFooterBodySpacing, unit );
+ lay->addWidget(m_footerSpacing);
+
+ lay = new QHBoxLayout(footnotePane);
+ m_footnoteSpacing = new KoUnitDoubleSpinBox( footnotePane, 0.0, 999.0, 0.5, kwhf.ptFootNoteBodySpacing, unit );
+ lay->addWidget(m_footnoteSpacing);
+
+ if ( kwhf.header == HF_FIRST_DIFF || kwhf.header == HF_FIRST_EO_DIFF )
+ rhFirst->setChecked( true );
+ if ( kwhf.header == HF_EO_DIFF || kwhf.header == HF_FIRST_EO_DIFF )
+ rhEvenOdd->setChecked( true );
+ if ( kwhf.footer == HF_FIRST_DIFF || kwhf.footer == HF_FIRST_EO_DIFF )
+ rfFirst->setChecked( true );
+ if ( kwhf.footer == HF_EO_DIFF || kwhf.footer == HF_FIRST_EO_DIFF )
+ rfEvenOdd->setChecked( true );
+}
+
+const KoKWHeaderFooter& KoPageLayoutHeader::headerFooter() {
+ if ( rhFirst->isChecked() && rhEvenOdd->isChecked() )
+ m_headerFooters.header = HF_FIRST_EO_DIFF;
+ else if ( rhFirst->isChecked() )
+ m_headerFooters.header = HF_FIRST_DIFF;
+ else if ( rhEvenOdd->isChecked() )
+ m_headerFooters.header = HF_EO_DIFF;
+ else
+ m_headerFooters.header = HF_SAME;
+
+ m_headerFooters.ptHeaderBodySpacing = m_headerSpacing->value();
+ m_headerFooters.ptFooterBodySpacing = m_footerSpacing->value();
+ m_headerFooters.ptFootNoteBodySpacing = m_footnoteSpacing->value();
+ if ( rfFirst->isChecked() && rfEvenOdd->isChecked() )
+ m_headerFooters.footer = HF_FIRST_EO_DIFF;
+ else if ( rfFirst->isChecked() )
+ m_headerFooters.footer = HF_FIRST_DIFF;
+ else if ( rfEvenOdd->isChecked() )
+ m_headerFooters.footer = HF_EO_DIFF;
+ else
+ m_headerFooters.footer = HF_SAME;
+ return m_headerFooters;
+}
diff --git a/lib/kofficeui/KoPageLayoutHeader.h b/lib/kofficeui/KoPageLayoutHeader.h
new file mode 100644
index 00000000..52239714
--- /dev/null
+++ b/lib/kofficeui/KoPageLayoutHeader.h
@@ -0,0 +1,56 @@
+/* This file is part of the KDE project
+ * Copyright (C) 2005 Thomas Zander <zander@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; version 2.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef kopagelayoutheader_h
+#define kopagelayoutheader_h
+
+#include <KoUnit.h>
+#include <KoPageLayout.h>
+#include <KoPageLayoutHeaderBase.h>
+
+class QWidget;
+class KoUnitDoubleSpinBox;
+class KoPagePreview;
+
+/**
+ * This class is a widget that shows the KoKWHeaderFooter data structure and allows the user to change it.
+ */
+class KoPageLayoutHeader : public KoPageLayoutHeaderBase {
+ Q_OBJECT
+
+public:
+ /**
+ * Contructor
+ * @param parent the parent widget
+ * @param unit the unit-type (mm/cm/inch) that the dialog should show
+ * @param kwhf the data that this widget will be filled with initially
+ */
+ KoPageLayoutHeader(QWidget *parent, KoUnit::Unit unit, const KoKWHeaderFooter &kwhf);
+ /**
+ * @return the altered data as it is currently set by the user.
+ */
+ const KoKWHeaderFooter& headerFooter();
+
+private:
+ KoUnitDoubleSpinBox *m_headerSpacing, *m_footerSpacing, *m_footnoteSpacing;
+
+ KoKWHeaderFooter m_headerFooters;
+};
+
+#endif
+
diff --git a/lib/kofficeui/KoPageLayoutHeaderBase.ui b/lib/kofficeui/KoPageLayoutHeaderBase.ui
new file mode 100644
index 00000000..d46ca98e
--- /dev/null
+++ b/lib/kofficeui/KoPageLayoutHeaderBase.ui
@@ -0,0 +1,221 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>KoPageLayoutHeaderBase</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>KoPageLayoutHeaderBase</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>445</width>
+ <height>437</height>
+ </rect>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>groupBox1</cstring>
+ </property>
+ <property name="title">
+ <string>Header</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>rhFirst</cstring>
+ </property>
+ <property name="text">
+ <string>Different header for the first page</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>rhEvenOdd</cstring>
+ </property>
+ <property name="text">
+ <string>Different header for even and odd pages</string>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout1</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <spacer>
+ <property name="name">
+ <cstring>spacer2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>21</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel3</cstring>
+ </property>
+ <property name="text">
+ <string>Spacing between header and body:</string>
+ </property>
+ </widget>
+ <widget class="QFrame">
+ <property name="name">
+ <cstring>headerSpacingPane</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Raised</enum>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>groupBox2</cstring>
+ </property>
+ <property name="title">
+ <string>Footer</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>rfFirst</cstring>
+ </property>
+ <property name="text">
+ <string>Different footer for the first page</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>rfEvenOdd</cstring>
+ </property>
+ <property name="text">
+ <string>Different footer for even and odd pages</string>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout2</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <spacer>
+ <property name="name">
+ <cstring>spacer3</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>41</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel4</cstring>
+ </property>
+ <property name="text">
+ <string>Spacing between footer and body:</string>
+ </property>
+ </widget>
+ <widget class="QFrame">
+ <property name="name">
+ <cstring>footerSpacingPane</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Raised</enum>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>groupBox3</cstring>
+ </property>
+ <property name="title">
+ <string>Footnote/Endnote</string>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <spacer>
+ <property name="name">
+ <cstring>spacer4</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel5</cstring>
+ </property>
+ <property name="text">
+ <string>Spacing between footnote and body:</string>
+ </property>
+ </widget>
+ <widget class="QFrame">
+ <property name="name">
+ <cstring>footnotePane</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Raised</enum>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+</widget>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/lib/kofficeui/KoPageLayoutSize.cpp b/lib/kofficeui/KoPageLayoutSize.cpp
new file mode 100644
index 00000000..6fdb23e6
--- /dev/null
+++ b/lib/kofficeui/KoPageLayoutSize.cpp
@@ -0,0 +1,350 @@
+/* This file is part of the KDE project
+ * Copyright (C) 1998, 1999 Reginald Stadlbauer <reggie@kde.org>
+ * Copyright (C) 2005 Thomas Zander <zander@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; version 2.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <KoPageLayoutDia.h>
+#include <KoPageLayoutSize.h>
+#include <KoUnit.h>
+#include <KoUnitWidgets.h>
+
+#include <klocale.h>
+#include <kiconloader.h>
+#include <kmessagebox.h>
+#include <kdebug.h>
+
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qradiobutton.h>
+#include <qhbox.h>
+#include <qvgroupbox.h>
+#include <qhbuttongroup.h>
+
+KoPageLayoutSize::KoPageLayoutSize(QWidget *parent, const KoPageLayout& layout, KoUnit::Unit unit,const KoColumns& columns, bool unitChooser, bool enableBorders)
+ : QWidget(parent), m_blockSignals(false) {
+ m_layout = layout;
+ m_unit = unit;
+
+ QGridLayout *grid1 = new QGridLayout( this, 5, 2, 0, KDialog::spacingHint() );
+ if ( unitChooser ) {
+ // ------------- unit _______________
+ QWidget* unitFrame = new QWidget( this );
+ grid1->addWidget( unitFrame, 0, 0, Qt::AlignLeft );
+ QBoxLayout* unitLayout = new QHBoxLayout( unitFrame, 0, KDialog::spacingHint() );
+
+ // label unit
+ QLabel *lpgUnit = new QLabel( i18n( "Unit:" ), unitFrame );
+ unitLayout->addWidget( lpgUnit, 0, Qt::AlignRight | Qt::AlignVCenter );
+
+ // combo unit
+ QComboBox *cpgUnit = new QComboBox( false, unitFrame, "cpgUnit" );
+ lpgUnit->setBuddy( cpgUnit );
+ cpgUnit->insertStringList( KoUnit::listOfUnitName() );
+ cpgUnit->setCurrentItem( unit );
+ unitLayout->addWidget( cpgUnit, 0, Qt::AlignLeft | Qt::AlignVCenter );
+ connect( cpgUnit, SIGNAL( activated( int ) ), this, SLOT( setUnitInt( int ) ) );
+ }
+ else {
+ QString str=KoUnit::unitDescription(unit);
+
+ QLabel *lpgUnit = new QLabel( i18n("All values are given in %1.").arg(str), this );
+ grid1->addWidget( lpgUnit, 0, 0, Qt::AlignLeft );
+ }
+
+ // -------------- page size -----------------
+ QVGroupBox *formatFrame = new QVGroupBox( i18n( "Page Size" ), this );
+ grid1->addWidget( formatFrame, 1, 0 );
+
+ QHBox *formatPageSize = new QHBox( formatFrame );
+ formatPageSize->setSpacing( KDialog::spacingHint() );
+
+ // label page size
+ QLabel *lpgFormat = new QLabel( i18n( "&Size:" ), formatPageSize );
+
+ // combo size
+ cpgFormat = new QComboBox( false, formatPageSize, "cpgFormat" );
+ cpgFormat->insertStringList( KoPageFormat::allFormats() );
+ lpgFormat->setBuddy( cpgFormat );
+ connect( cpgFormat, SIGNAL( activated( int ) ), this, SLOT( formatChanged( int ) ) );
+
+ // spacer
+ formatPageSize->setStretchFactor( new QWidget( formatPageSize ), 10 );
+
+ QHBox *formatCustomSize = new QHBox( formatFrame );
+ formatCustomSize->setSpacing( KDialog::spacingHint() );
+
+ // label width
+ QLabel *lpgWidth = new QLabel( i18n( "&Width:" ), formatCustomSize );
+
+ // linedit width
+ epgWidth = new KoUnitDoubleSpinBox( formatCustomSize, "Width" );
+ lpgWidth->setBuddy( epgWidth );
+ if ( m_layout.format != PG_CUSTOM )
+ epgWidth->setEnabled( false );
+ connect( epgWidth, SIGNAL( valueChangedPt(double) ), this, SLOT( widthChanged(double) ) );
+
+ // label height
+ QLabel *lpgHeight = new QLabel( i18n( "&Height:" ), formatCustomSize );
+
+ // linedit height
+ epgHeight = new KoUnitDoubleSpinBox( formatCustomSize, "Height" );
+ lpgHeight->setBuddy( epgHeight );
+ if ( m_layout.format != PG_CUSTOM )
+ epgHeight->setEnabled( false );
+ connect( epgHeight, SIGNAL( valueChangedPt(double ) ), this, SLOT( heightChanged(double) ) );
+
+ // --------------- orientation ---------------
+ m_orientGroup = new QHButtonGroup( i18n( "Orientation" ), this );
+ m_orientGroup->setInsideSpacing( KDialog::spacingHint() );
+ grid1->addWidget( m_orientGroup, 2, 0 );
+
+ QLabel* lbPortrait = new QLabel( m_orientGroup );
+ lbPortrait->setPixmap( QPixmap( UserIcon( "koPortrait" ) ) );
+ lbPortrait->setMaximumWidth( lbPortrait->pixmap()->width() );
+ new QRadioButton( i18n("&Portrait"), m_orientGroup );
+
+ QLabel* lbLandscape = new QLabel( m_orientGroup );
+ lbLandscape->setPixmap( QPixmap( UserIcon( "koLandscape" ) ) );
+ lbLandscape->setMaximumWidth( lbLandscape->pixmap()->width() );
+ new QRadioButton( i18n("La&ndscape"), m_orientGroup );
+
+ connect( m_orientGroup, SIGNAL (clicked (int)), this, SLOT( orientationChanged(int) ));
+
+ // --------------- page margins ---------------
+ QVGroupBox *marginsFrame = new QVGroupBox( i18n( "Margins" ), this );
+ marginsFrame->setColumnLayout( 0, Qt::Vertical );
+ marginsFrame->setMargin( KDialog::marginHint() );
+ grid1->addWidget( marginsFrame, 3, 0 );
+
+ QGridLayout *marginsLayout = new QGridLayout( marginsFrame->layout(), 3, 3,
+ KDialog::spacingHint() );
+
+ // left margin
+ ebrLeft = new KoUnitDoubleSpinBox( marginsFrame, "Left" );
+ marginsLayout->addWidget( ebrLeft, 1, 0 );
+ connect( ebrLeft, SIGNAL( valueChangedPt( double ) ), this, SLOT( leftChanged( double ) ) );
+
+ // right margin
+ ebrRight = new KoUnitDoubleSpinBox( marginsFrame, "Right" );
+ marginsLayout->addWidget( ebrRight, 1, 2 );
+ connect( ebrRight, SIGNAL( valueChangedPt( double ) ), this, SLOT( rightChanged( double ) ) );
+
+ // top margin
+ ebrTop = new KoUnitDoubleSpinBox( marginsFrame, "Top" );
+ marginsLayout->addWidget( ebrTop, 0, 1 , Qt::AlignCenter );
+ connect( ebrTop, SIGNAL( valueChangedPt( double ) ), this, SLOT( topChanged( double ) ) );
+
+ // bottom margin
+ ebrBottom = new KoUnitDoubleSpinBox( marginsFrame, "Bottom" );
+ marginsLayout->addWidget( ebrBottom, 2, 1, Qt::AlignCenter );
+ connect( ebrBottom, SIGNAL( valueChangedPt( double ) ), this, SLOT( bottomChanged( double ) ) );
+
+ // ------------- preview -----------
+ pgPreview = new KoPagePreview( this, "Preview", m_layout );
+ grid1->addMultiCellWidget( pgPreview, 1, 3, 1, 1 );
+
+ // ------------- spacers -----------
+ QWidget* spacer1 = new QWidget( this );
+ QWidget* spacer2 = new QWidget( this );
+ spacer1->setSizePolicy( QSizePolicy( QSizePolicy::Expanding,
+ QSizePolicy::Expanding ) );
+ spacer2->setSizePolicy( QSizePolicy( QSizePolicy::Expanding,
+ QSizePolicy::Expanding ) );
+ grid1->addWidget( spacer1, 4, 0 );
+ grid1->addWidget( spacer2, 4, 1 );
+
+ setValues();
+ updatePreview();
+ pgPreview->setPageColumns( columns );
+ setEnableBorders(enableBorders);
+}
+
+void KoPageLayoutSize::setEnableBorders(bool on) {
+ m_haveBorders = on;
+ ebrLeft->setEnabled( on );
+ ebrRight->setEnabled( on );
+ ebrTop->setEnabled( on );
+ ebrBottom->setEnabled( on );
+
+ // update m_layout
+ m_layout.ptLeft = on?ebrLeft->value():0;
+ m_layout.ptRight = on?ebrRight->value():0;
+ m_layout.ptTop = on?ebrTop->value():0;
+ m_layout.ptBottom = on?ebrBottom->value():0;
+
+ // use updated m_layout
+ updatePreview();
+ emit propertyChange(m_layout);
+}
+
+void KoPageLayoutSize::updatePreview() {
+ pgPreview->setPageLayout( m_layout );
+}
+
+void KoPageLayoutSize::setValues() {
+ // page format
+ cpgFormat->setCurrentItem( m_layout.format );
+ // orientation
+ m_orientGroup->setButton( m_layout.orientation == PG_PORTRAIT ? 0: 1 );
+
+ setUnit( m_unit );
+ updatePreview();
+}
+
+void KoPageLayoutSize::setUnit( KoUnit::Unit unit ) {
+ m_unit = unit;
+ m_blockSignals = true; // due to non-atomic changes the propertyChange emits should be blocked
+
+ epgWidth->setUnit( m_unit );
+ epgWidth->setMinMaxStep( 0, KoUnit::fromUserValue( 9999, m_unit ), KoUnit::fromUserValue( 0.01, m_unit ) );
+ epgWidth->changeValue( m_layout.ptWidth );
+
+ epgHeight->setUnit( m_unit );
+ epgHeight->setMinMaxStep( 0, KoUnit::fromUserValue( 9999, m_unit ), KoUnit::fromUserValue( 0.01, m_unit ) );
+ epgHeight->changeValue( m_layout.ptHeight );
+
+ double dStep = KoUnit::fromUserValue( 0.2, m_unit );
+
+ ebrLeft->setUnit( m_unit );
+ ebrLeft->changeValue( m_layout.ptLeft );
+ ebrLeft->setMinMaxStep( 0, m_layout.ptWidth, dStep );
+
+ ebrRight->setUnit( m_unit );
+ ebrRight->changeValue( m_layout.ptRight );
+ ebrRight->setMinMaxStep( 0, m_layout.ptWidth, dStep );
+
+ ebrTop->setUnit( m_unit );
+ ebrTop->changeValue( m_layout.ptTop );
+ ebrTop->setMinMaxStep( 0, m_layout.ptHeight, dStep );
+
+ ebrBottom->setUnit( m_unit );
+ ebrBottom->changeValue( m_layout.ptBottom );
+ ebrBottom->setMinMaxStep( 0, m_layout.ptHeight, dStep );
+
+ m_blockSignals = false;
+}
+
+void KoPageLayoutSize::setUnitInt( int unit ) {
+ setUnit((KoUnit::Unit)unit);
+}
+
+void KoPageLayoutSize::formatChanged( int format ) {
+ if ( ( KoFormat )format == m_layout.format )
+ return;
+ m_layout.format = ( KoFormat )format;
+ bool enable = (KoFormat) format == PG_CUSTOM;
+ epgWidth->setEnabled( enable );
+ epgHeight->setEnabled( enable );
+
+ if ( m_layout.format != PG_CUSTOM ) {
+ m_layout.ptWidth = MM_TO_POINT( KoPageFormat::width(
+ m_layout.format, m_layout.orientation ) );
+ m_layout.ptHeight = MM_TO_POINT( KoPageFormat::height(
+ m_layout.format, m_layout.orientation ) );
+ }
+
+ epgWidth->changeValue( m_layout.ptWidth );
+ epgHeight->changeValue( m_layout.ptHeight );
+
+ updatePreview( );
+ emit propertyChange(m_layout);
+}
+
+void KoPageLayoutSize::orientationChanged(int which) {
+ m_layout.orientation = which == 0 ? PG_PORTRAIT : PG_LANDSCAPE;
+
+ // swap dimension
+ double val = epgWidth->value();
+ epgWidth->changeValue(epgHeight->value());
+ epgHeight->changeValue(val);
+ // and adjust margins
+ m_blockSignals = true;
+ val = ebrTop->value();
+ if(m_layout.orientation == PG_PORTRAIT) { // clockwise
+ ebrTop->changeValue(ebrRight->value());
+ ebrRight->changeValue(ebrBottom->value());
+ ebrBottom->changeValue(ebrLeft->value());
+ ebrLeft->changeValue(val);
+ } else { // counter clockwise
+ ebrTop->changeValue(ebrLeft->value());
+ ebrLeft->changeValue(ebrBottom->value());
+ ebrBottom->changeValue(ebrRight->value());
+ ebrRight->changeValue(val);
+ }
+ m_blockSignals = false;
+
+ setEnableBorders(m_haveBorders); // will update preview+emit
+}
+
+void KoPageLayoutSize::widthChanged(double width) {
+ if(m_blockSignals) return;
+ m_layout.ptWidth = width;
+ updatePreview();
+ emit propertyChange(m_layout);
+}
+void KoPageLayoutSize::heightChanged(double height) {
+ if(m_blockSignals) return;
+ m_layout.ptHeight = height;
+ updatePreview( );
+ emit propertyChange(m_layout);
+}
+void KoPageLayoutSize::leftChanged( double left ) {
+ if(m_blockSignals) return;
+ m_layout.ptLeft = left;
+ updatePreview();
+ emit propertyChange(m_layout);
+}
+void KoPageLayoutSize::rightChanged(double right) {
+ if(m_blockSignals) return;
+ m_layout.ptRight = right;
+ updatePreview();
+ emit propertyChange(m_layout);
+}
+void KoPageLayoutSize::topChanged(double top) {
+ if(m_blockSignals) return;
+ m_layout.ptTop = top;
+ updatePreview();
+ emit propertyChange(m_layout);
+}
+void KoPageLayoutSize::bottomChanged(double bottom) {
+ if(m_blockSignals) return;
+ m_layout.ptBottom = bottom;
+ updatePreview();
+ emit propertyChange(m_layout);
+}
+
+bool KoPageLayoutSize::queryClose() {
+ if ( m_layout.ptLeft + m_layout.ptRight > m_layout.ptWidth ) {
+ KMessageBox::error( this,
+ i18n("The page width is smaller than the left and right margins."),
+ i18n("Page Layout Problem") );
+ return false;
+ }
+ if ( m_layout.ptTop + m_layout.ptBottom > m_layout.ptHeight ) {
+ KMessageBox::error( this,
+ i18n("The page height is smaller than the top and bottom margins."),
+ i18n("Page Layout Problem") );
+ return false;
+ }
+ return true;
+}
+
+void KoPageLayoutSize::setColumns(KoColumns &columns) {
+ pgPreview->setPageColumns(columns);
+}
+
+#include <KoPageLayoutSize.moc>
diff --git a/lib/kofficeui/KoPageLayoutSize.h b/lib/kofficeui/KoPageLayoutSize.h
new file mode 100644
index 00000000..ebdf49b6
--- /dev/null
+++ b/lib/kofficeui/KoPageLayoutSize.h
@@ -0,0 +1,118 @@
+/* This file is part of the KDE project
+ * Copyright (C) 1998, 1999 Reginald Stadlbauer <reggie@kde.org>
+ * Copyright (C) 2005 Thomas Zander <zander@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; version 2.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef kopagelayoutsize_h
+#define kopagelayoutsize_h
+
+#include <qgroupbox.h>
+#include <KoGlobal.h>
+#include <KoUnit.h>
+#include <kdialogbase.h>
+#include <KoPageLayout.h>
+#include <KoPageLayoutDia.h>
+
+class QComboBox;
+class KoUnitDoubleSpinBox;
+class KoPageLayoutColumns;
+
+/**
+ * This class is a widget that shows the KoPageLayout data structure and allows the user to change it.
+ */
+class KoPageLayoutSize : public QWidget {
+ Q_OBJECT
+
+public:
+ /**
+ * Contructor
+ * @param parent the parent widget
+ * @param layout the page layout that this widget should be initialzed with.
+ * @param unit the unit-type (mm/cm/inch) that the dialog should show
+ * @param columns the KoColumns (amout of columns) that the preview should be initialized with
+ * @param unitChooser if true a combobox with the unit-type is shown for the user to change
+ * @param enableBorders if true enable the user to change the margins (aka borders) of the page
+ */
+ KoPageLayoutSize(QWidget *parent, const KoPageLayout& layout, KoUnit::Unit unit,
+ const KoColumns& columns, bool unitChooser, bool enableBorders);
+
+ /**
+ * @return if the dialog is in a sane state and the values can be used.
+ */
+ bool queryClose();
+ /**
+ * Update the page preview widget with the param columns.
+ * @param columns the new columns
+ */
+ void setColumns(KoColumns &columns);
+
+ KoUnit::Unit unit() { return m_unit; }
+
+public slots:
+ /**
+ * Set a new unit for the widget updating the widgets.
+ * @param unit the new unit
+ */
+ void setUnit( KoUnit::Unit unit );
+ /**
+ * Enable the user to edit the page border size
+ * @param on if true enable the user to change the margins (aka borders) of the page
+ */
+ void setEnableBorders(bool on);
+
+signals:
+ /**
+ * Emitted whenever the user changed something in the dialog.
+ * @param layout the update layout structure with currently displayed info.
+ * Note that the info may not be fully correct and physically possible (in which
+ * case queryClose will return false)
+ */
+ void propertyChange(KoPageLayout &layout);
+
+protected:
+ QComboBox *cpgFormat;
+ KoUnitDoubleSpinBox *epgWidth;
+ KoUnitDoubleSpinBox *epgHeight;
+ KoUnitDoubleSpinBox *ebrLeft;
+ KoUnitDoubleSpinBox *ebrRight;
+ KoUnitDoubleSpinBox *ebrTop;
+ KoUnitDoubleSpinBox *ebrBottom;
+ KoPagePreview *pgPreview;
+ QButtonGroup *m_orientGroup;
+
+protected slots:
+ void formatChanged( int );
+ void widthChanged( double );
+ void heightChanged( double );
+ void leftChanged( double );
+ void rightChanged( double );
+ void topChanged( double );
+ void bottomChanged( double );
+ void orientationChanged( int );
+ void setUnitInt( int unit );
+
+private:
+ void updatePreview();
+ void setValues();
+
+ KoUnit::Unit m_unit;
+ KoPageLayout m_layout;
+
+ bool m_blockSignals, m_haveBorders;
+};
+
+#endif
diff --git a/lib/kofficeui/KoPartSelectAction.cpp b/lib/kofficeui/KoPartSelectAction.cpp
new file mode 100644
index 00000000..f6795cf9
--- /dev/null
+++ b/lib/kofficeui/KoPartSelectAction.cpp
@@ -0,0 +1,80 @@
+/* This file is part of the KDE libraries
+ Copyright (C) 2001 David Faure <faure@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#include "KoPartSelectAction.h"
+#include "KoPartSelectDia.h"
+
+#include <kdebug.h>
+
+KoPartSelectAction::KoPartSelectAction( const QString& text, QObject* parent, const char* name )
+ : KActionMenu( text, parent, name )
+{
+ init();
+}
+
+KoPartSelectAction::KoPartSelectAction( const QString& text, const QString& icon,
+ QObject* parent, const char* name )
+ : KActionMenu( text, icon, parent, name )
+{
+ init();
+}
+
+KoPartSelectAction::KoPartSelectAction( const QString& text, const QString& icon,
+ QObject* receiver, const char* slot,
+ QObject* parent, const char* name )
+ : KActionMenu( text, icon, parent, name )
+{
+ if (receiver)
+ connect( this, SIGNAL( activated() ), receiver, slot );
+ init();
+}
+
+void KoPartSelectAction::init()
+{
+ // Query for documents
+ m_lstEntries = KoDocumentEntry::query();
+ QValueList<KoDocumentEntry>::Iterator it = m_lstEntries.begin();
+ for( ; it != m_lstEntries.end(); ++it ) {
+ KService::Ptr serv = (*it).service();
+ if (!serv->genericName().isEmpty()) {
+ KAction *action = new KAction( serv->genericName().replace('&',"&&"), serv->icon(), 0,
+ this, SLOT( slotActionActivated() ),
+ parentCollection(), serv->name().latin1() );
+ insert( action );
+ }
+ }
+
+}
+
+// Called when selecting a part
+void KoPartSelectAction::slotActionActivated()
+{
+ QString servName = QString::fromLatin1( sender()->name() );
+ KService::Ptr serv = KService::serviceByName( servName );
+ m_documentEntry = KoDocumentEntry( serv );
+ emit activated();
+}
+
+// Called when activating the toolbar button
+void KoPartSelectAction::slotActivated()
+{
+ m_documentEntry = KoPartSelectDia::selectPart( 0L );
+ emit activated();
+}
+
+#include "KoPartSelectAction.moc"
diff --git a/lib/kofficeui/KoPartSelectAction.h b/lib/kofficeui/KoPartSelectAction.h
new file mode 100644
index 00000000..4926dd9e
--- /dev/null
+++ b/lib/kofficeui/KoPartSelectAction.h
@@ -0,0 +1,57 @@
+/* This file is part of the KDE libraries
+ Copyright (C) 2001 David Faure <faure@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#ifndef koPartSelectAction_h
+#define koPartSelectAction_h
+
+#include <kaction.h>
+#include <KoQueryTrader.h>
+
+/**
+ * An action for inserting an embedded object.
+ * In a toolbar it presents itself as a button that opens the part-select dialog,
+ * but in a popupmenu it presents itself as a submenu with all available parts.
+ */
+class KOFFICEUI_EXPORT KoPartSelectAction : public KActionMenu
+{
+ Q_OBJECT
+
+public:
+ KoPartSelectAction( const QString& text, QObject* parent = 0, const char* name = 0 );
+ KoPartSelectAction( const QString& text, const QString& icon,
+ QObject* parent = 0, const char* name = 0 );
+ KoPartSelectAction( const QString& text, const QString& icon,
+ QObject* receiver, const char* slot, QObject* parent, const char* name = 0 );
+
+ KoDocumentEntry documentEntry() const { return m_documentEntry; }
+
+ //virtual void plug(QWidget* widget, int index);
+
+protected:
+ void init();
+
+protected slots:
+ virtual void slotActivated();
+ void slotActionActivated();
+
+private:
+ QValueList<KoDocumentEntry> m_lstEntries;
+ KoDocumentEntry m_documentEntry;
+};
+
+#endif
diff --git a/lib/kofficeui/KoPartSelectDia.cpp b/lib/kofficeui/KoPartSelectDia.cpp
new file mode 100644
index 00000000..773d1b88
--- /dev/null
+++ b/lib/kofficeui/KoPartSelectDia.cpp
@@ -0,0 +1,93 @@
+/* This file is part of the KDE libraries
+ Copyright (C) 1998 Torben Weis <weis@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#include <KoPartSelectDia.h>
+
+#include <kiconloader.h>
+#include <klocale.h>
+#include <qlistview.h>
+
+/****************************************************
+ *
+ * KoPartSelectDia
+ *
+ ****************************************************/
+
+KoPartSelectDia::KoPartSelectDia( QWidget* parent, const char* name ) :
+ KDialogBase( parent, name, TRUE, i18n("Insert Object"), KDialogBase::Ok | KDialogBase::Cancel )
+{
+ listview = new QListView( this );
+ listview->addColumn( i18n( "Object" ) );
+ listview->addColumn( i18n( "Comment" ) );
+ listview->setAllColumnsShowFocus( TRUE );
+ listview->setShowSortIndicator( TRUE );
+ setMainWidget( listview );
+ connect( listview, SIGNAL( doubleClicked( QListViewItem * ) ),
+ this, SLOT( slotOk() ) );
+ connect( listview, SIGNAL( selectionChanged( QListViewItem * ) ),
+ this, SLOT( selectionChanged( QListViewItem * ) ) );
+
+ // Query for documents
+ m_lstEntries = KoDocumentEntry::query();
+ QValueList<KoDocumentEntry>::Iterator it = m_lstEntries.begin();
+ for( ; it != m_lstEntries.end(); ++it ) {
+ KService::Ptr serv = (*it).service();
+ if (!serv->genericName().isEmpty()) {
+ QListViewItem *item = new QListViewItem( listview, serv->name(), serv->genericName() );
+ item->setPixmap( 0, SmallIcon( serv->icon() ) );
+ }
+ }
+
+ selectionChanged( 0 );
+ setFocus();
+ resize( listview->sizeHint().width() + 20, 300 );
+}
+
+void KoPartSelectDia::selectionChanged( QListViewItem *item )
+{
+ enableButtonOK( item != 0 );
+}
+
+KoDocumentEntry KoPartSelectDia::entry()
+{
+ if ( listview->currentItem() ) {
+ QValueList<KoDocumentEntry>::Iterator it = m_lstEntries.begin();
+ for ( ; it != m_lstEntries.end(); ++it ) {
+ if ( ( *it ).service()->name() == listview->currentItem()->text( 0 ) )
+ return *it;
+ }
+ }
+ return KoDocumentEntry();
+}
+
+KoDocumentEntry KoPartSelectDia::selectPart( QWidget *parent )
+{
+ KoDocumentEntry e;
+
+ KoPartSelectDia *dlg = new KoPartSelectDia( parent, "PartSelect" );
+ dlg->setFocus();
+ if (dlg->exec() == QDialog::Accepted)
+ e = dlg->entry();
+
+ delete dlg;
+
+ return e;
+}
+
+#include <KoPartSelectDia.moc>
diff --git a/lib/kofficeui/KoPartSelectDia.h b/lib/kofficeui/KoPartSelectDia.h
new file mode 100644
index 00000000..b7af305d
--- /dev/null
+++ b/lib/kofficeui/KoPartSelectDia.h
@@ -0,0 +1,70 @@
+/* This file is part of the KDE libraries
+ Copyright (C) 1998 Torben Weis <weis@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#ifndef DlgPartSelect_included
+#define DlgPartSelect_included
+
+#include <kdialogbase.h>
+#include <KoQueryTrader.h>
+
+class QListView;
+class QListViewItem;
+class QPushButton;
+
+/**
+ * This dialog presents the user all available
+ * KOffice components ( KSpread, KWord etc ) with name
+ * and mini icon. The user may select one and
+ * the corresponding KoDocumentEntry is returned.
+ */
+class KOFFICEUI_EXPORT KoPartSelectDia : public KDialogBase
+{
+ Q_OBJECT
+
+public:
+
+ /**
+ * Constructor.
+ */
+ KoPartSelectDia( QWidget* parent = 0, const char* name = 0 );
+
+ /**
+ * Retrieves the result of the part selection.
+ *
+ * @return A document entry.
+ */
+ KoDocumentEntry entry();
+
+ /**
+ * Convenience function for using the dialog.
+ *
+ * @returns the KoDocumentEntry of the selected KOffice components
+ * or an empty entry.
+ */
+ static KoDocumentEntry selectPart( QWidget *parent = 0L );
+
+private slots:
+ void selectionChanged( QListViewItem * );
+
+private:
+ QValueList<KoDocumentEntry> m_lstEntries;
+ QListView *listview;
+};
+
+#endif
diff --git a/lib/kofficeui/KoPen.cpp b/lib/kofficeui/KoPen.cpp
new file mode 100644
index 00000000..4fa77af1
--- /dev/null
+++ b/lib/kofficeui/KoPen.cpp
@@ -0,0 +1,69 @@
+/* This file is part of the KDE project
+ Copyright (C) 2005 Peter Simonsson
+ Copyright (C) 2005 Thorsten Zachmann <zachmann@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+#include "KoPen.h"
+
+#include <../kotext/KoTextZoomHandler.h>
+
+KoPen::KoPen()
+ : QPen()
+{
+ m_pointWidth = 1.0;
+}
+
+KoPen::KoPen(const QColor& _color, double _pointWidth, Qt::PenStyle _style)
+ : QPen()
+{
+ setColor(_color);
+ setPointWidth(_pointWidth);
+ setStyle(_style);
+}
+
+KoPen::KoPen(const QColor& _color)
+ : QPen(_color)
+{
+ m_pointWidth = 1.0;
+}
+
+KoPen::~KoPen()
+{
+}
+
+bool KoPen::operator==( const KoPen &p ) const
+{
+ return color() == p.color() && style() == p.style() && m_pointWidth == p.pointWidth();
+}
+
+bool KoPen::operator!=( const KoPen &p ) const
+{
+ return color() != p.color() || style() != p.style() || m_pointWidth != p.pointWidth();
+}
+
+void KoPen::setPointWidth(double w)
+{
+ m_pointWidth = w;
+}
+
+QPen KoPen::zoomedPen(KoZoomHandler* zoomHandler)
+{
+ QPen pen = *this;
+ pen.setWidth(zoomHandler->zoomItY(m_pointWidth));
+
+ return pen;
+}
diff --git a/lib/kofficeui/KoPen.h b/lib/kofficeui/KoPen.h
new file mode 100644
index 00000000..87124cef
--- /dev/null
+++ b/lib/kofficeui/KoPen.h
@@ -0,0 +1,68 @@
+/* This file is part of the KDE project
+ Copyright (C) 2005 Peter Simonsson
+ Copyright (C) 2005 Thorsten Zachmann <zachmann@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+#ifndef KOPEN_H
+#define KOPEN_H
+
+#include <qpen.h>
+
+class KoZoomHandler;
+
+/**
+ * Pen that handles line widths in points
+ */
+class KoPen : public QPen
+{
+ public:
+ KoPen();
+ KoPen(const QColor& _color, double _pointWidth, Qt::PenStyle _style);
+ KoPen(const QColor& _color);
+ ~KoPen();
+
+ /**
+ * @brief Compare pens if they are equal
+ *
+ * Two pens are equal if they have equal styles, widths and colors.
+ *
+ * @return true if the pens are equal, false otherwise
+ */
+ bool operator==( const KoPen &p ) const;
+
+ /**
+ * @brief Compare pens if they differ
+ *
+ * Two pens are different if they have different styles, widths or colors.
+ *
+ * @return true if the pens are different, false otherwise
+ */
+ bool operator!=( const KoPen &p ) const;
+
+ /// Set the pen width in points
+ void setPointWidth(double width);
+ /// KoPen width in points
+ double pointWidth() const { return m_pointWidth; }
+
+ /// Returns a zoomed QPen
+ QPen zoomedPen(KoZoomHandler* zoomHandler);
+
+ private:
+ double m_pointWidth;
+};
+
+#endif
diff --git a/lib/kofficeui/KoPictureFilePreview.cpp b/lib/kofficeui/KoPictureFilePreview.cpp
new file mode 100644
index 00000000..7f27b940
--- /dev/null
+++ b/lib/kofficeui/KoPictureFilePreview.cpp
@@ -0,0 +1,121 @@
+/* This file is part of the KDE project
+ Copyright (C) 1998, 1999 Reginald Stadlbauer <reggie@kde.org>
+ Copyright (C) 2002 Nicolas GOUTTE <goutte@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#include "KoPictureFilePreview.h"
+#include "KoPictureFilePreview.moc"
+#include <kdialog.h>
+#include <klocale.h>
+#include <kurl.h>
+#include <qbitmap.h>
+#include <qlayout.h>
+#include <qfileinfo.h>
+#include <qpainter.h>
+#include <qscrollview.h>
+
+#include <kdebug.h>
+
+#include <KoPicture.h>
+
+/**
+ * This class implements the actual widget that shows the image.
+ * It is a scrollview, to have scrollbars if the image is big,
+ * and it supports both pixmaps and cliparts
+ */
+class KoPictureFilePreviewWidget : public QScrollView
+{
+public:
+ KoPictureFilePreviewWidget( QWidget *parent )
+ : QScrollView( parent ) { viewport()->setBackgroundMode( PaletteBase ); }
+
+ bool setPicture( const KURL& url )
+ {
+ KoPicture picture;
+ if ( url.isLocalFile() )
+ {
+ if ( !picture.loadFromFile( url.path() ) )
+ {
+ return false;
+ }
+ }
+ else
+ {
+ // ### TODO: find a way to avoid to download the file again later
+ if ( !picture.setKeyAndDownloadPicture( url, this ) )
+ {
+ return false;
+ }
+ }
+ m_size = picture.getOriginalSize();
+ m_picture = picture;
+ resizeContents( m_size.width(), m_size.height() );
+ repaintContents();
+ return true;
+ }
+
+ void setNullPicture(void)
+ {
+ m_picture=KoPicture();
+ m_size=QSize();
+ }
+
+ void drawContents( QPainter *p, int, int, int, int )
+ {
+ p->setBackgroundColor( Qt::white );
+ // Be sure that the background is white (for transparency)
+ p->fillRect(0, 0, m_size.width(), m_size.height(), QBrush( Qt::white ));
+ m_picture.draw( *p, 0 ,0, m_size.width(), m_size.height());
+ }
+
+private:
+ KoPicture m_picture;
+ QSize m_size;
+};
+
+KoPictureFilePreview::KoPictureFilePreview( QWidget *parent )
+ : KPreviewWidgetBase( parent )
+{
+ QVBoxLayout *vb = new QVBoxLayout( this, KDialog::marginHint() );
+ m_widget = new KoPictureFilePreviewWidget( this );
+ vb->addWidget( m_widget, 1 );
+}
+
+void KoPictureFilePreview::showPreview( const KURL &u )
+{
+ m_widget->setPicture( u );
+}
+
+void KoPictureFilePreview::clearPreview()
+{
+ m_widget->setNullPicture();
+}
+
+QString KoPictureFilePreview::clipartPattern()
+{
+ return i18n( "*.svg *.wmf *.qpic|Clipart (*.svg *.wmf *.qpic)" );
+}
+
+QStringList KoPictureFilePreview::clipartMimeTypes()
+{
+ QStringList lst;
+ lst << "image/svg+xml";
+ lst << "image/x-wmf";
+ lst << "image/x-vnd.trolltech.qpicture";
+ return lst;
+}
diff --git a/lib/kofficeui/KoPictureFilePreview.h b/lib/kofficeui/KoPictureFilePreview.h
new file mode 100644
index 00000000..28d6a3e6
--- /dev/null
+++ b/lib/kofficeui/KoPictureFilePreview.h
@@ -0,0 +1,67 @@
+/* This file is part of the KDE project
+ Copyright (C) 1998, 1999 Reginald Stadlbauer <reggie@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#ifndef kopicturefilepreview_h
+#define kopicturefilepreview_h
+
+#include <kpreviewwidgetbase.h>
+#include <koffice_export.h>
+class KoPictureFilePreviewWidget;
+
+/**
+ * A preview widget for KFileDialog that supports both pixmaps and cliparts.
+ *
+ * If fd is a KFileDialog *,
+ * fd->setPreviewWidget( new KoPictureFilePreview( fd ) );
+ */
+class KOFFICEUI_EXPORT KoPictureFilePreview : public KPreviewWidgetBase
+{
+ Q_OBJECT
+
+public:
+ KoPictureFilePreview( QWidget *parent );
+
+ /**
+ * @return a list of patterns of all supported clipart formats.
+ *
+ * These patterns can be passed to KFileDialog::getOpenFileName
+ * for instance.
+ */
+ static QString clipartPattern();
+
+ /**
+ * @return list of mimetypes for all supported clipart formats.
+ */
+ static QStringList clipartMimeTypes();
+
+public slots:
+ virtual void showPreview(const KURL &url);
+ virtual void clearPreview();
+
+private:
+ KoPictureFilePreviewWidget *m_widget;
+ // m_widget can act as a d pointer for BC purposes, no need for another one
+};
+
+#endif
+
+
+
+
+
diff --git a/lib/kofficeui/KoRuler.cpp b/lib/kofficeui/KoRuler.cpp
new file mode 100644
index 00000000..e0ced466
--- /dev/null
+++ b/lib/kofficeui/KoRuler.cpp
@@ -0,0 +1,1202 @@
+/* This file is part of the KDE project
+ Copyright (C) 1998, 1999 Reginald Stadlbauer <reggie@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+// Description: Ruler (header)
+
+/******************************************************************/
+
+#include "KoRuler.h"
+#include <klocale.h>
+#include <kglobalsettings.h>
+#include <kdebug.h>
+#include <kiconloader.h>
+#include <qcursor.h>
+#include <qpainter.h>
+#include <qpopupmenu.h>
+#include <qtooltip.h>
+#include <KoPageLayout.h>
+
+class KoRulerPrivate {
+public:
+ KoRulerPrivate() {
+ }
+ ~KoRulerPrivate() {}
+
+ QWidget *canvas;
+ int flags;
+ int oldMx, oldMy;
+ bool whileMovingBorderLeft, whileMovingBorderRight;
+ bool whileMovingBorderTop, whileMovingBorderBottom;
+ QPixmap pmFirst, pmLeft;
+ KoPageLayout layout;
+ KoTabChooser *tabChooser;
+ KoTabulatorList tabList;
+ // Do we have to remove a certain tab in the DC Event?
+ KoTabulator removeTab;
+ // The tab we're moving / clicking on - basically only valid between press and release time
+ KoTabulator currTab;
+ // The action we're currently doing - basically only valid between press and release time
+ KoRuler::Action action;
+ QPopupMenu *rb_menu;
+ int mRemoveTab, mPageLayout; // menu item ids
+ int frameEnd;
+ double i_right;
+ bool m_bReadWrite;
+ bool doubleClickedIndent;
+ bool rtl;
+ bool mousePressed;
+};
+
+// Equality test for tab positions in particular
+static inline bool equals( double a, double b ) {
+ return kAbs( a - b ) < 1E-4;
+}
+
+
+/******************************************************************/
+/* Class: KoRuler */
+/******************************************************************/
+
+const int KoRuler::F_TABS = 1;
+const int KoRuler::F_INDENTS = 2;
+const int KoRuler::F_HELPLINES = 4;
+const int KoRuler::F_NORESIZE = 8;
+
+/*================================================================*/
+KoRuler::KoRuler( QWidget *_parent, QWidget *_canvas, Orientation _orientation,
+ const KoPageLayout& _layout, int _flags, KoUnit::Unit _unit, KoTabChooser *_tabChooser )
+ : QFrame( _parent ), buffer( width(), height() ), m_zoom(1.0), m_1_zoom(1.0),
+ m_unit( _unit )
+{
+ setWFlags( WResizeNoErase | WRepaintNoErase );
+ setFrameStyle( MenuBarPanel );
+
+ d=new KoRulerPrivate();
+
+ d->tabChooser = _tabChooser;
+
+ d->canvas = _canvas;
+ orientation = _orientation;
+ d->layout = _layout;
+ d->flags = _flags;
+
+ d->m_bReadWrite=true;
+ d->doubleClickedIndent=false;
+ diffx = 0;
+ diffy = 0;
+ i_left=0.0;
+ i_first=0.0;
+ d->i_right=0.0;
+
+ setMouseTracking( true );
+ d->mousePressed = false;
+ d->action = A_NONE;
+
+ d->oldMx = 0;
+ d->oldMy = 0;
+ d->rtl = false;
+
+ showMPos = false;
+ mposX = 0;
+ mposY = 0;
+ gridSize=0.0;
+ hasToDelete = false;
+ d->whileMovingBorderLeft = d->whileMovingBorderRight = d->whileMovingBorderTop = d->whileMovingBorderBottom = false;
+
+ d->pmFirst = UserIcon( "koRulerFirst" );
+ d->pmLeft = UserIcon( "koRulerLeft" );
+ d->currTab.type = T_INVALID;
+
+ d->removeTab.type = T_INVALID;
+ if ( orientation == Qt::Horizontal ) {
+ frameStart = qRound( zoomIt(d->layout.ptLeft) );
+ d->frameEnd = qRound( zoomIt(d->layout.ptWidth - d->layout.ptRight) );
+ } else {
+ frameStart = qRound( zoomIt(d->layout.ptTop) );
+ d->frameEnd = qRound( zoomIt(d->layout.ptHeight - d->layout.ptBottom) );
+ }
+ m_bFrameStartSet = false;
+
+ setupMenu();
+
+ // For compatibility, emitting doubleClicked shall emit openPageLayoutDia
+ connect( this, SIGNAL( doubleClicked() ), this, SIGNAL( openPageLayoutDia() ) );
+}
+
+/*================================================================*/
+KoRuler::~KoRuler()
+{
+ delete d->rb_menu;
+ delete d;
+}
+
+void KoRuler::setPageLayoutMenuItemEnabled(bool b)
+{
+ d->rb_menu->setItemEnabled(d->mPageLayout, b);
+}
+
+/*================================================================*/
+void KoRuler::setMousePos( int mx, int my )
+{
+ if ( !showMPos || ( mx == mposX && my == mposY ) ) return;
+
+ QPainter p( this );
+ p.setRasterOp( Qt::NotROP );
+
+ if ( orientation == Qt::Horizontal ) {
+ if ( hasToDelete )
+ p.drawLine( mposX, 1, mposX, height() - 1 );
+ p.drawLine( mx, 1, mx, height() - 1 );
+ hasToDelete = true;
+ }
+ else {
+ if ( hasToDelete )
+ p.drawLine( 1, mposY, width() - 1, mposY );
+ p.drawLine( 1, my, width() - 1, my );
+ hasToDelete = true;
+ }
+ p.end();
+
+ mposX = mx;
+ mposY = my;
+}
+
+// distance between the main lines (those with a number)
+double KoRuler::lineDistance() const
+{
+ switch( m_unit ) {
+ case KoUnit::U_INCH:
+ return INCH_TO_POINT( m_zoom ); // every inch
+ case KoUnit::U_PT:
+ return 100.0 * m_zoom; // every 100 pt
+ case KoUnit::U_MM:
+ case KoUnit::U_CM:
+ case KoUnit::U_DM:
+ return CM_TO_POINT ( m_zoom ); // every cm
+ case KoUnit::U_PI:
+ return PI_TO_POINT ( 10.0 * m_zoom ); // every 10 pica
+ case KoUnit::U_DD:
+ return DD_TO_POINT( m_zoom ); // every diderot
+ case KoUnit::U_CC:
+ return CC_TO_POINT( 10.0 * m_zoom ); // every 10 cicero
+ }
+ // should never end up here
+ return 100.0 * m_zoom;
+}
+
+/*================================================================*/
+void KoRuler::drawHorizontal( QPainter *_painter )
+{
+ QFont font = KGlobalSettings::toolBarFont();
+ QFontMetrics fm( font );
+ resize( width(), QMAX( fm.height() + 4, 20 ) );
+
+ // Use a double-buffer pixmap
+ QPainter p( &buffer );
+ p.fillRect( 0, 0, width(), height(), QBrush( colorGroup().brush( QColorGroup::Background ) ) );
+
+ int totalw = qRound( zoomIt(d->layout.ptWidth) );
+ QString str;
+
+ p.setBrush( colorGroup().brush( QColorGroup::Base ) );
+
+ // Draw white rect
+ QRect r;
+ if ( !d->whileMovingBorderLeft )
+ r.setLeft( -diffx + frameStart );
+ else
+ r.setLeft( d->oldMx );
+ r.setTop( 0 );
+ if ( !d->whileMovingBorderRight )
+ r.setWidth(d->frameEnd-frameStart);
+ else
+ r.setRight( d->oldMx );
+ r.setBottom( height() );
+
+ p.drawRect( r );
+ p.setFont( font );
+
+ // Draw the numbers
+ double dist = lineDistance();
+ int maxwidth = 0;
+
+ for ( double i = 0.0;i <= (double)totalw;i += dist ) {
+ str = QString::number( KoUnit::toUserValue( i / m_zoom, m_unit ) );
+ int textwidth = fm.width( str );
+ maxwidth = QMAX( maxwidth, textwidth );
+ }
+
+ // Make sure that the ruler stays readable at lower zoom levels
+ while( dist <= maxwidth ) {
+ dist += lineDistance();
+ }
+
+ for ( double i = 0.0;i <= (double)totalw;i += dist ) {
+ str = QString::number( KoUnit::toUserValue( i / m_zoom, m_unit ) );
+ int textwidth = fm.width( str );
+ maxwidth = QMAX( maxwidth, textwidth );
+ p.drawText( qRound(i) - diffx - qRound(textwidth * 0.5),
+ qRound(( height() - fm.height() ) * 0.5),
+ textwidth, height(), AlignLeft | AlignTop, str );
+ }
+
+ // Draw the medium-sized lines
+ // Only if we have enough space (i.e. not at 33%)
+ if ( dist > maxwidth + 2 )
+ {
+ for ( double i = dist * 0.5;i <= (double)totalw;i += dist ) {
+ int ii=qRound(i);
+ p.drawLine( ii - diffx, 7, ii - diffx, height() - 7 );
+ }
+ }
+
+ // Draw the small lines
+ // Only if we have enough space (i.e. not at 33%)
+ if ( dist * 0.5 > maxwidth + 2 )
+ {
+ for ( double i = dist * 0.25;i <= (double)totalw;i += dist * 0.5 ) {
+ int ii=qRound(i);
+ p.drawLine( ii - diffx, 9, ii - diffx, height() - 9 );
+ }
+ }
+
+ // Draw ending bar (at page width)
+ //int constant=zoomIt(1);
+ //p.drawLine( totalw - diffx + constant, 1, totalw - diffx + constant, height() - 1 );
+ //p.setPen( colorGroup().color( QColorGroup::Base ) );
+ //p.drawLine( totalw - diffx, 1, totalw - diffx, height() - 1 );
+
+ // Draw starting bar (at 0)
+ //p.setPen( colorGroup().color( QColorGroup::Text ) );
+ //p.drawLine( -diffx, 1, -diffx, height() - 1 );
+ //p.setPen( colorGroup().color( QColorGroup::Base ) );
+ //p.drawLine( -diffx - constant, 1, -diffx - constant, height() - 1 );
+
+ // Draw the indents triangles
+ if ( d->flags & F_INDENTS ) {
+ int top = 1;
+ double halfPixmapWidth = d->pmFirst.width() * 0.5;
+ // Cumulate i_first with correct indent
+ double firstLineIdent = i_first + ( d->rtl ? d->i_right : i_left );
+ p.drawPixmap( qRound( static_cast<double>(r.left()) + applyRtlAndZoom( firstLineIdent ) - halfPixmapWidth ),
+ top, d->pmFirst );
+
+ int bottom = height() - d->pmLeft.height() - 1;
+ halfPixmapWidth = d->pmLeft.width() * 0.5;
+ p.drawPixmap( qRound( static_cast<double>(r.left()) + zoomIt(i_left) - halfPixmapWidth ),
+ bottom, d->pmLeft );
+ p.drawPixmap( qRound( static_cast<double>(r.right()) - zoomIt(d->i_right) - halfPixmapWidth ),
+ bottom, d->pmLeft );
+ }
+
+ // Show the mouse position
+ if ( d->action == A_NONE && showMPos ) {
+ p.setPen( colorGroup().color( QColorGroup::Text ) );
+ p.drawLine( mposX, 1, mposX, height() - 1 );
+ }
+ hasToDelete = false;
+
+ // Draw the tabs
+ if ( d->tabChooser && ( d->flags & F_TABS ) && !d->tabList.isEmpty() )
+ drawTabs( p );
+
+ p.end();
+ _painter->drawPixmap( 0, 0, buffer );
+}
+
+/*================================================================*/
+void KoRuler::drawTabs( QPainter &_painter )
+{
+ int ptPos = 0;
+
+ _painter.setPen( QPen( colorGroup().color( QColorGroup::Text ), 2, SolidLine ) );
+ // Check if we're in a mousemove event, removing a tab.
+ // In that case, we'll have to skip drawing that one.
+ bool willRemove = d->mousePressed && willRemoveTab( d->oldMy ) && d->currTab.type != T_INVALID;
+
+ KoTabulatorList::ConstIterator it = d->tabList.begin();
+ for ( ; it != d->tabList.end() ; it++ ) {
+ if ( willRemove && equals( d->currTab.ptPos, (*it).ptPos ) )
+ continue;
+ ptPos = qRound(applyRtlAndZoom((*it).ptPos)) - diffx + frameStart;
+ switch ( (*it).type ) {
+ case T_LEFT: {
+ ptPos -= 4;
+ _painter.drawLine( ptPos + 4, height() - 4, ptPos + 20 - 4, height() - 4 );
+ _painter.drawLine( ptPos + 5, 4, ptPos + 5, height() - 4 );
+ } break;
+ case T_CENTER: {
+ ptPos -= 10;
+ _painter.drawLine( ptPos + 4, height() - 4, ptPos + 20 - 4, height() - 4 );
+ _painter.drawLine( ptPos + 20 / 2, 4, ptPos + 20 / 2, height() - 4 );
+ } break;
+ case T_RIGHT: {
+ ptPos -= 16;
+ _painter.drawLine( ptPos + 4, height() - 4, ptPos + 20 - 4, height() - 4 );
+ _painter.drawLine( ptPos + 20 - 5, 4, ptPos + 20 - 5, height() - 4 );
+ } break;
+ case T_DEC_PNT: {
+ ptPos -= 10;
+ _painter.drawLine( ptPos + 4, height() - 4, ptPos + 20 - 4, height() - 4 );
+ _painter.drawLine( ptPos + 20 / 2, 4, ptPos + 20 / 2, height() - 4 );
+ _painter.fillRect( ptPos + 20 / 2 + 2, height() - 9, 3, 3,
+ colorGroup().color( QColorGroup::Text ) );
+ } break;
+ default: break;
+ }
+ }
+}
+
+/*================================================================*/
+void KoRuler::drawVertical( QPainter *_painter )
+{
+ QFont font = KGlobalSettings::toolBarFont();
+ QFontMetrics fm( font );
+ resize( QMAX( fm.height() + 4, 20 ), height() );
+
+ QPainter p( &buffer );
+ p.fillRect( 0, 0, width(), height(), QBrush( colorGroup().brush( QColorGroup::Background ) ) );
+
+ int totalh = qRound( zoomIt(d->layout.ptHeight) );
+ // Clip rect - this gives basically always a rect like (2,2,width-2,height-2)
+ QRect paintRect = _painter->clipRegion( QPainter::CoordPainter ).boundingRect();
+ // Ruler rect
+ QRect rulerRect( 0, -diffy, width(), totalh );
+
+ if ( paintRect.intersects( rulerRect ) ) {
+ QString str;
+
+ p.setBrush( colorGroup().brush( QColorGroup::Base ) );
+
+ // Draw white rect
+ QRect r;
+ if ( !d->whileMovingBorderTop )
+ r.setTop( -diffy + frameStart );
+ else
+ r.setTop( d->oldMy );
+ r.setLeft( 0 );
+ if ( !d->whileMovingBorderBottom )
+ r.setHeight(d->frameEnd-frameStart);
+ else
+ r.setBottom( d->oldMy );
+ r.setRight( width() );
+
+ p.drawRect( r );
+ p.setFont( font );
+
+ // Draw the numbers
+ double dist = lineDistance();
+ int maxheight = 0;
+
+ for ( double i = 0.0;i <= (double)totalh;i += dist ) {
+ str = QString::number( KoUnit::toUserValue( i / m_zoom, m_unit ) );
+ int textwidth = fm.width( str );
+ maxheight = QMAX( maxheight, textwidth );
+ }
+
+ // Make sure that the ruler stays readable at lower zoom levels
+ while( dist <= maxheight ) {
+ dist += lineDistance();
+ }
+
+ for ( double i = 0.0;i <= (double)totalh;i += dist ) {
+ str = QString::number( KoUnit::toUserValue( i / m_zoom, m_unit ) );
+ int textwidth = fm.width( str );
+ int yOffset = qRound(i) - diffy + qRound(textwidth * 0.5);
+ if(yOffset > paintRect.bottom())
+ break; // stop drawing when outside the to-paint-region
+ int textheight = fm.height();
+ maxheight = QMAX( maxheight, textwidth );
+ p.save();
+ p.translate( qRound(( width() - textheight ) * 0.5), yOffset);
+ p.rotate( -90 );
+ p.drawText( 0, 0, textwidth + 1, textheight, AlignLeft | AlignTop, str );
+ p.restore();
+ }
+
+ // Draw the medium-sized lines
+ if ( dist > maxheight + 2 )
+ {
+ for ( double i = dist * 0.5;i <= (double)totalh;i += dist ) {
+ int ii=qRound(i) - diffy;
+ if(ii > paintRect.bottom())
+ break; // stop drawing when outside the to-paint-region
+ p.drawLine( 7, ii, width() - 7, ii);
+ }
+ }
+
+ // Draw the small lines
+ if ( dist * 0.5 > maxheight + 2 )
+ {
+ for ( double i = dist * 0.25;i <=(double)totalh;i += dist *0.5 ) {
+ int ii=qRound(i) - diffy;
+ if(ii > paintRect.bottom())
+ break; // stop drawing when outside the to-paint-region
+ p.drawLine( 9, ii, width() - 9, ii);
+ }
+ }
+
+ // Draw ending bar (at page height)
+ //p.drawLine( 1, totalh - diffy + 1, width() - 1, totalh - diffy + 1 );
+ //p.setPen( colorGroup().color( QColorGroup::Base ) );
+ //p.drawLine( 1, totalh - diffy, width() - 1, totalh - diffy );
+
+ // Draw starting bar (at 0)
+ //p.setPen( colorGroup().color( QColorGroup::Text ) );
+ //p.drawLine( 1, -diffy, width() - 1, -diffy );
+ //p.setPen( colorGroup().color( QColorGroup::Base ) );
+ //p.drawLine( 1, -diffy - 1, width() - 1, -diffy - 1 );
+ }
+
+ // Show the mouse position
+ if ( d->action == A_NONE && showMPos ) {
+ p.setPen( colorGroup().color( QColorGroup::Text ) );
+ p.drawLine( 1, mposY, width() - 1, mposY );
+ }
+ hasToDelete = false;
+
+ p.end();
+ _painter->drawPixmap( 0, 0, buffer );
+}
+
+void KoRuler::mousePressEvent( QMouseEvent *e )
+{
+ if( !d->m_bReadWrite)
+ return;
+
+ d->oldMx = e->x();
+ d->oldMy = e->y();
+ d->mousePressed = true;
+ d->removeTab.type = T_INVALID;
+
+ switch ( e->button() ) {
+ case RightButton:
+ if(d->currTab.type == T_INVALID || !(d->flags & F_TABS))
+ d->rb_menu->setItemEnabled(d->mRemoveTab, false);
+ else
+ d->rb_menu->setItemEnabled(d->mRemoveTab, true);
+ d->rb_menu->popup( QCursor::pos() );
+ d->action = A_NONE;
+ d->mousePressed = false;
+ return;
+ case MidButton:
+ // MMB shall do like double-click (it opens a dialog).
+ handleDoubleClick();
+ return;
+ case LeftButton:
+ if ( d->action == A_BR_RIGHT || d->action == A_BR_LEFT ) {
+ if ( d->action == A_BR_RIGHT )
+ d->whileMovingBorderRight = true;
+ else
+ d->whileMovingBorderLeft = true;
+
+ if ( d->canvas )
+ drawLine(d->oldMx, -1);
+ update();
+ } else if ( d->action == A_BR_TOP || d->action == A_BR_BOTTOM ) {
+ if ( d->action == A_BR_TOP )
+ d->whileMovingBorderTop = true;
+ else
+ d->whileMovingBorderBottom = true;
+
+ if ( d->canvas ) {
+ QPainter p( d->canvas );
+ p.setRasterOp( Qt::NotROP );
+ p.drawLine( 0, d->oldMy, d->canvas->width(), d->oldMy );
+ p.end();
+ }
+ update();
+ } else if ( d->action == A_FIRST_INDENT || d->action == A_LEFT_INDENT || d->action == A_RIGHT_INDENT ) {
+ if ( d->canvas )
+ drawLine(d->oldMx, -1);
+ } else if ( d->action == A_TAB ) {
+ if ( d->canvas && d->currTab.type != T_INVALID ) {
+ drawLine( qRound( applyRtlAndZoom(d->currTab.ptPos) ) + frameStart - diffx, -1 );
+ }
+ } else if ( d->tabChooser && ( d->flags & F_TABS ) && d->tabChooser->getCurrTabType() != 0 ) {
+ int left = frameStart - diffx;
+ int right = d->frameEnd - diffx;
+
+ if( e->x()-left < 0 || right-e->x() < 0 )
+ return;
+ KoTabulator tab;
+ tab.filling = TF_BLANK;
+ tab.ptWidth = 0.5;
+ switch ( d->tabChooser->getCurrTabType() ) {
+ case KoTabChooser::TAB_LEFT:
+ tab.type = T_LEFT;
+ break;
+ case KoTabChooser::TAB_CENTER:
+ tab.type = T_CENTER;
+ break;
+ case KoTabChooser::TAB_RIGHT:
+ tab.type = T_RIGHT;
+ break;
+ case KoTabChooser::TAB_DEC_PNT:
+ tab.type = T_DEC_PNT;
+ tab.alignChar = KGlobal::locale()->decimalSymbol()[0];
+ break;
+ default: break;
+ }
+ tab.ptPos = unZoomItRtl( e->x() + diffx - frameStart );
+
+ KoTabulatorList::Iterator it=d->tabList.begin();
+ while ( it!=d->tabList.end() && tab > (*it) )
+ ++it;
+
+ d->tabList.insert(it, tab);
+
+ d->action = A_TAB;
+ d->removeTab = tab;
+ d->currTab = tab;
+
+ emit tabListChanged( d->tabList );
+ update();
+ }
+ else if ( d->flags & F_HELPLINES )
+ {
+ setCursor( orientation == Qt::Horizontal ?
+ Qt::sizeVerCursor : Qt::sizeHorCursor );
+ d->action = A_HELPLINES;
+ }
+ default:
+ break;
+ }
+}
+
+void KoRuler::mouseReleaseEvent( QMouseEvent *e )
+{
+ d->mousePressed = false;
+
+ // Hacky, but necessary to prevent multiple tabs with the same coordinates (Werner)
+ bool fakeMovement=false;
+ if(d->removeTab.type != T_INVALID) {
+ mouseMoveEvent(e);
+ fakeMovement=true;
+ }
+
+ if ( d->action == A_BR_RIGHT || d->action == A_BR_LEFT ) {
+ d->whileMovingBorderRight = false;
+ d->whileMovingBorderLeft = false;
+
+ if ( d->canvas )
+ drawLine(d->oldMx, -1);
+ update();
+ emit newPageLayout( d->layout );
+ } else if ( d->action == A_BR_TOP || d->action == A_BR_BOTTOM ) {
+ d->whileMovingBorderTop = false;
+ d->whileMovingBorderBottom = false;
+
+ if ( d->canvas ) {
+ QPainter p( d->canvas );
+ p.setRasterOp( Qt::NotROP );
+ p.drawLine( 0, d->oldMy, d->canvas->width(), d->oldMy );
+ p.end();
+ }
+ update();
+ emit newPageLayout( d->layout );
+ } else if ( d->action == A_FIRST_INDENT ) {
+ if ( d->canvas )
+ drawLine(d->oldMx, -1);
+ update();
+ emit newFirstIndent( i_first );
+ } else if ( d->action == A_LEFT_INDENT ) {
+ if ( d->canvas )
+ drawLine(d->oldMx, -1);
+ update();
+ emit newLeftIndent( i_left );
+ } else if ( d->action == A_RIGHT_INDENT ) {
+ if ( d->canvas )
+ drawLine(d->oldMx, -1);
+ update();
+ emit newRightIndent( d->i_right );
+ } else if ( d->action == A_TAB ) {
+ if ( d->canvas && !fakeMovement ) {
+ drawLine( qRound( applyRtlAndZoom( d->currTab.ptPos ) ) + frameStart - diffx, -1);
+ }
+ if ( willRemoveTab( e->y() ) )
+ {
+ d->tabList.remove(d->currTab);
+ }
+ qHeapSort( d->tabList );
+
+ // Delete the new tabulator if it is placed on top of another.
+ KoTabulatorList::ConstIterator tmpTab=d->tabList.begin();
+ int count=0;
+ while(tmpTab!=d->tabList.end()) {
+ if( equals( (*tmpTab).ptPos, d->currTab.ptPos ) ) {
+ count++;
+ if(count > 1) {
+ d->tabList.remove(d->currTab);
+ break;
+ }
+ }
+ tmpTab++;
+ }
+ //searchTab( e->x() ); // DF: why set currTab here?
+ emit tabListChanged( d->tabList );
+ update();
+ }
+ else if( d->action == A_HELPLINES )
+ {
+ emit addGuide( e->pos(), orientation == Qt::Horizontal, orientation == Qt::Horizontal ? size().height() : size().width() );
+ emit addHelpline( e->pos(), orientation == Qt::Horizontal);
+ setCursor( ArrowCursor );
+ }
+ d->currTab.type = T_INVALID; // added (DF)
+}
+
+void KoRuler::mouseMoveEvent( QMouseEvent *e )
+{
+ hasToDelete = false;
+
+ int pw = d->frameEnd - frameStart;
+ int ph = qRound(zoomIt(d->layout.ptHeight));
+ int left = frameStart - diffx;
+ int top = qRound(zoomIt(d->layout.ptTop));
+ top -= diffy;
+ int right = d->frameEnd - diffx;
+ int bottom = qRound(zoomIt(d->layout.ptBottom));
+ bottom = ph - bottom - diffy;
+ // Cumulate first-line-indent
+ int ip_first = qRound( zoomIt( i_first + ( d->rtl ? d->i_right : i_left) ) );
+ int ip_left = qRound(zoomIt(i_left));
+ int ip_right = qRound(zoomIt(d->i_right));
+
+ int mx = e->x();
+ mx = mx+diffx < 0 ? 0 : mx;
+ int my = e->y();
+ my = my+diffy < 0 ? 0 : my;
+
+ QToolTip::remove( this);
+ switch ( orientation ) {
+ case Qt::Horizontal: {
+ if ( !d->mousePressed ) {
+ setCursor( ArrowCursor );
+ d->action = A_NONE;
+ /////// ######
+ // At the moment, moving the left and right border indicators
+ // is disabled when setFrameStartEnd has been called (i.e. in KWord)
+ // Changing the layout margins directly from it would be utterly wrong
+ // (just try the 2-columns modes...). What needs to be done is:
+ // emitting a signal frameResized in mouseReleaseEvent, when a left/right
+ // border has been moved, and in kword we need to update the margins from
+ // there, if the left border of the 1st column or the right border of the
+ // last column was moved... and find what to do with the other borders.
+ // And for normal frames, resize the frame without touching the page layout.
+ // All that is too much for now -> disabling.
+ if ( !m_bFrameStartSet )
+ {
+ if ( mx > left - 5 && mx < left + 5 ) {
+ setCursor( Qt::sizeHorCursor );
+ d->action = A_BR_LEFT;
+ } else if ( mx > right - 5 && mx < right + 5 ) {
+ setCursor( Qt::sizeHorCursor );
+ d->action = A_BR_RIGHT;
+ }
+ }
+ if ( d->flags & F_INDENTS ) {
+ int firstX = d->rtl ? right - ip_first : left + ip_first;
+ if ( mx > firstX - 5 && mx < firstX + 5 &&
+ my >= 2 && my <= d->pmFirst.size().height() + 2 ) {
+ QToolTip::add( this, i18n("First line indent") );
+ setCursor( ArrowCursor );
+ d->action = A_FIRST_INDENT;
+ } else if ( mx > left + ip_left - 5 && mx < left + ip_left + 5 &&
+ my >= height() - d->pmLeft.size().height() - 2 && my <= height() - 2 ) {
+ QToolTip::add( this, i18n("Left indent") );
+ setCursor( ArrowCursor );
+ d->action = A_LEFT_INDENT;
+ } else if ( mx > right - ip_right - 5 && mx < right - ip_right + 5 &&
+ my >= height() - d->pmLeft.size().height() - 2 && my <= height() - 2 ) {
+ QToolTip::add( this, i18n("Right indent") );
+ setCursor( ArrowCursor );
+ d->action = A_RIGHT_INDENT;
+ }
+ }
+ if ( d->flags & F_TABS )
+ searchTab(mx);
+ } else {
+ // Calculate the new value.
+ int newPos=mx;
+ if( newPos!=right && gridSize!=0.0 && (e->state() & ShiftButton)==0) { // apply grid.
+ double grid=zoomIt(gridSize * 16);
+ newPos=qRound( ((newPos * 16 / grid) * grid) / 16 );
+ }
+ if(newPos-left < 0) newPos=left;
+ else if (right-newPos < 0) newPos=right;
+ double newValue = unZoomIt(static_cast<double>(newPos) - frameStart + diffx);
+
+ switch ( d->action ) {
+ case A_BR_LEFT: {
+ if ( d->canvas && mx < right-10 && mx+diffx-2 > 0) {
+ drawLine( d->oldMx, mx );
+ d->layout.ptLeft = unZoomIt(static_cast<double>(mx + diffx));
+ if( ip_left > right-left-15 ) {
+ ip_left=right-left-15;
+ ip_left=ip_left<0 ? 0 : ip_left;
+ i_left=unZoomIt( ip_left );
+ emit newLeftIndent( i_left );
+ }
+ if ( ip_right > right-left-15 ) {
+ ip_right=right-left-15;
+ ip_right=ip_right<0? 0 : ip_right;
+ d->i_right=unZoomIt( ip_right );
+ emit newRightIndent( d->i_right );
+ }
+ d->oldMx = mx;
+ d->oldMy = my;
+ update();
+ }
+ else
+ return;
+ } break;
+ case A_BR_RIGHT: {
+ if ( d->canvas && mx > left+10 && mx+diffx <= pw-2) {
+ drawLine( d->oldMx, mx );
+ d->layout.ptRight = unZoomIt(static_cast<double>(pw - ( mx + diffx )));
+ if( ip_left > right-left-15 ) {
+ ip_left=right-left-15;
+ ip_left=ip_left<0 ? 0 : ip_left;
+ i_left=unZoomIt( ip_left );
+ emit newLeftIndent( i_left );
+ }
+ if ( ip_right > right-left-15 ) {
+ ip_right=right-left-15;
+ ip_right=ip_right<0? 0 : ip_right;
+ d->i_right=unZoomIt( ip_right );
+ emit newRightIndent( d->i_right );
+ }
+ d->oldMx = mx;
+ d->oldMy = my;
+ update();
+ }
+ else
+ return;
+ } break;
+ case A_FIRST_INDENT: {
+ if ( d->canvas ) {
+ if (d->rtl)
+ newValue = unZoomIt(pw) - newValue - d->i_right;
+ else
+ newValue -= i_left;
+ if(newValue == i_first) break;
+ drawLine( d->oldMx, newPos);
+ d->oldMx=newPos;
+ i_first = newValue;
+ update();
+ }
+ } break;
+ case A_LEFT_INDENT: {
+ if ( d->canvas ) {
+ //if (d->rtl) newValue = unZoomIt(pw) - newValue;
+ if(newValue == i_left) break;
+
+ drawLine( d->oldMx, newPos);
+ i_left = newValue;
+ d->oldMx = newPos;
+ update();
+ }
+ } break;
+ case A_RIGHT_INDENT: {
+ if ( d->canvas ) {
+ double rightValue = unZoomIt(right - newPos);
+ //if (d->rtl) rightValue = unZoomIt(pw) - rightValue;
+ if(rightValue == d->i_right) break;
+
+ drawLine( d->oldMx, newPos);
+ d->i_right=rightValue;
+ d->oldMx = newPos;
+ update();
+ }
+ } break;
+ case A_TAB: {
+ if ( d->canvas) {
+ if (d->rtl) newValue = unZoomIt(pw) - newValue;
+ if(newValue == d->currTab.ptPos) break; // no change
+ QPainter p( d->canvas );
+ p.setRasterOp( Qt::NotROP );
+ // prevent 1st drawLine when we just created a new tab
+ // (it's a NOT line)
+ double pt;
+ int pt_fr;
+ if( d->currTab != d->removeTab )
+ {
+ pt = applyRtlAndZoom(d->currTab.ptPos);
+ pt_fr = qRound(pt) + frameStart - diffx;
+ p.drawLine( pt_fr, 0, pt_fr, d->canvas->height() );
+ }
+
+ KoTabulatorList::Iterator it = d->tabList.find( d->currTab );
+ Q_ASSERT( it != d->tabList.end() );
+ if ( it != d->tabList.end() )
+ (*it).ptPos = newValue;
+ d->currTab.ptPos = newValue;
+
+ pt = applyRtlAndZoom( newValue );
+ pt_fr = qRound(pt) + frameStart - diffx;
+ p.drawLine( pt_fr, 0, pt_fr, d->canvas->height() );
+
+ p.end();
+ d->oldMx = mx;
+ d->oldMy = my;
+ d->removeTab.type = T_INVALID;
+ update();
+ }
+ } break;
+ default: break;
+ }
+ }
+ if( d->action == A_HELPLINES )
+ {
+ emit moveGuide( e->pos(), true, size().height() );
+ emit moveHelpLines( e->pos(), true );
+ }
+
+ return;
+ } break;
+ case Qt::Vertical: {
+ if ( !d->mousePressed ) {
+ setCursor( ArrowCursor );
+ d->action = A_NONE;
+ if ( d->flags & F_NORESIZE )
+ break;
+ if ( my > top - 5 && my < top + 5 ) {
+ QToolTip::add( this, i18n("Top margin") );
+ setCursor( Qt::sizeVerCursor );
+ d->action = A_BR_TOP;
+ } else if ( my > bottom - 5 && my < bottom + 5 ) {
+ QToolTip::add( this, i18n("Bottom margin") );
+ setCursor( Qt::sizeVerCursor );
+ d->action = A_BR_BOTTOM;
+ }
+ } else {
+ switch ( d->action ) {
+ case A_BR_TOP: {
+ if ( d->canvas && my < bottom-20 && my+diffy-2 > 0) {
+ QPainter p( d->canvas );
+ p.setRasterOp( Qt::NotROP );
+ p.drawLine( 0, d->oldMy, d->canvas->width(), d->oldMy );
+ p.drawLine( 0, my, d->canvas->width(), my );
+ p.end();
+ d->layout.ptTop = unZoomIt(static_cast<double>(my + diffy));
+ d->oldMx = mx;
+ d->oldMy = my;
+ update();
+ }
+ else
+ return;
+ } break;
+ case A_BR_BOTTOM: {
+ if ( d->canvas && my > top+20 && my+diffy < ph-2) {
+ QPainter p( d->canvas );
+ p.setRasterOp( Qt::NotROP );
+ p.drawLine( 0, d->oldMy, d->canvas->width(), d->oldMy );
+ p.drawLine( 0, my, d->canvas->width(), my );
+ p.end();
+ d->layout.ptBottom = unZoomIt(static_cast<double>(ph - ( my + diffy )));
+ d->oldMx = mx;
+ d->oldMy = my;
+ update();
+ }
+ else
+ return;
+ } break;
+ default: break;
+ }
+ }
+
+ if( d->action == A_HELPLINES )
+ {
+ emit moveGuide( e->pos(), false, size().width() );
+ emit moveHelpLines( e->pos(), false );
+ }
+ } break;
+ }
+
+ d->oldMx = mx;
+ d->oldMy = my;
+}
+
+void KoRuler::resizeEvent( QResizeEvent *e )
+{
+ QFrame::resizeEvent( e );
+ buffer.resize( size() );
+}
+
+void KoRuler::mouseDoubleClickEvent( QMouseEvent* )
+{
+ handleDoubleClick();
+}
+
+void KoRuler::handleDoubleClick()
+{
+ if ( !d->m_bReadWrite )
+ return;
+
+ d->doubleClickedIndent = false;
+ if ( d->tabChooser && ( d->flags & F_TABS ) ) {
+ // Double-click and mousePressed inserted a tab -> need to remove it
+ if ( d->tabChooser->getCurrTabType() != 0 && d->removeTab.type != T_INVALID && !d->tabList.isEmpty()) {
+ uint c = d->tabList.count();
+ d->tabList.remove( d->removeTab );
+ Q_ASSERT( d->tabList.count() < c );
+
+ d->removeTab.type = T_INVALID;
+ d->currTab.type = T_INVALID;
+ emit tabListChanged( d->tabList );
+ setCursor( ArrowCursor );
+ update();
+ // --- we didn't click on a tab, fall out to indents test ---
+ } else if ( d->action == A_TAB ) {
+ // Double-click on a tab
+ emit doubleClicked( d->currTab.ptPos ); // usually paragraph dialog
+ return;
+ }
+ }
+
+ // When Binary Compatibility is broken this will hopefully emit a
+ // doubleClicked(int) to differentiate between double-clicking an
+ // indent and double-clicking the ruler
+ if ( d->flags & F_INDENTS ) {
+ if ( d->action == A_LEFT_INDENT || d->action == A_RIGHT_INDENT || d->action == A_FIRST_INDENT ) {
+ d->doubleClickedIndent = true;
+ emit doubleClicked(); // usually paragraph dialog
+ return;
+ }
+ }
+
+ // Double-clicked nothing
+ d->action = A_NONE;
+ emit doubleClicked(); // usually page layout dialog
+}
+
+void KoRuler::setTabList( const KoTabulatorList & _tabList )
+{
+ d->tabList = _tabList;
+ qHeapSort(d->tabList); // "Trust no one." as opposed to "In David we trust."
+
+ // Note that d->currTab and d->removeTab could now point to
+ // tabs which don't exist in d->tabList
+
+ update();
+}
+
+double KoRuler::makeIntern( double _v )
+{
+ return KoUnit::fromUserValue( _v, m_unit );
+}
+
+void KoRuler::setupMenu()
+{
+ d->rb_menu = new QPopupMenu();
+ Q_CHECK_PTR( d->rb_menu );
+ for ( uint i = 0 ; i <= KoUnit::U_LASTUNIT ; ++i )
+ {
+ KoUnit::Unit unit = static_cast<KoUnit::Unit>( i );
+ d->rb_menu->insertItem( KoUnit::unitDescription( unit ), i /*as id*/ );
+ if ( m_unit == unit )
+ d->rb_menu->setItemChecked( i, true );
+ }
+ connect( d->rb_menu, SIGNAL( activated( int ) ), SLOT( slotMenuActivated( int ) ) );
+
+ d->rb_menu->insertSeparator();
+ d->mPageLayout=d->rb_menu->insertItem(i18n("Page Layout..."), this, SLOT(pageLayoutDia()));
+ d->rb_menu->insertSeparator();
+ d->mRemoveTab=d->rb_menu->insertItem(i18n("Remove Tabulator"), this, SLOT(rbRemoveTab()));
+ d->rb_menu->setItemEnabled( d->mRemoveTab, false );
+}
+
+void KoRuler::uncheckMenu()
+{
+ for ( uint i = 0 ; i <= KoUnit::U_LASTUNIT ; ++i )
+ d->rb_menu->setItemChecked( i, false );
+}
+
+void KoRuler::setUnit( const QString& _unit )
+{
+ setUnit( KoUnit::unit( _unit ) );
+}
+
+void KoRuler::setUnit( KoUnit::Unit unit )
+{
+ m_unit = unit;
+ uncheckMenu();
+ d->rb_menu->setItemChecked( m_unit, true );
+ update();
+}
+
+void KoRuler::setZoom( const double& zoom )
+{
+ if(zoom==m_zoom)
+ return;
+ if(zoom < 1E-4) // Don't do 0 or negative values
+ return;
+ m_zoom=zoom;
+ m_1_zoom=1/m_zoom;
+ update();
+}
+
+bool KoRuler::willRemoveTab( int y ) const
+{
+ return (y < -50 || y > height() + 25) && d->currTab.type != T_INVALID;
+}
+
+void KoRuler::rbRemoveTab() {
+
+ d->tabList.remove( d->currTab );
+ d->currTab.type = T_INVALID;
+ emit tabListChanged( d->tabList );
+ update();
+}
+
+void KoRuler::setReadWrite(bool _readWrite)
+{
+ d->m_bReadWrite=_readWrite;
+}
+
+void KoRuler::searchTab(int mx) {
+
+ int pos;
+ d->currTab.type = T_INVALID;
+ KoTabulatorList::ConstIterator it = d->tabList.begin();
+ for ( ; it != d->tabList.end() ; ++it ) {
+ pos = qRound(applyRtlAndZoom((*it).ptPos)) - diffx + frameStart;
+ if ( mx > pos - 5 && mx < pos + 5 ) {
+ setCursor( Qt::sizeHorCursor );
+ d->action = A_TAB;
+ d->currTab = *it;
+ break;
+ }
+ }
+}
+
+void KoRuler::drawLine(int oldX, int newX) {
+
+ QPainter p( d->canvas );
+ p.setRasterOp( Qt::NotROP );
+ p.drawLine( oldX, 0, oldX, d->canvas->height() );
+ if(newX!=-1)
+ p.drawLine( newX, 0, newX, d->canvas->height() );
+ p.end();
+}
+
+void KoRuler::showMousePos( bool _showMPos )
+{
+ showMPos = _showMPos;
+ hasToDelete = false;
+ mposX = -1;
+ mposY = -1;
+ update();
+}
+
+void KoRuler::setOffset( int _diffx, int _diffy )
+{
+ //kdDebug() << "KoRuler::setOffset " << _diffx << "," << _diffy << endl;
+ diffx = _diffx;
+ diffy = _diffy;
+ update();
+}
+
+void KoRuler::setFrameStartEnd( int _frameStart, int _frameEnd )
+{
+ if ( _frameStart != frameStart || _frameEnd != d->frameEnd || !m_bFrameStartSet )
+ {
+ frameStart = _frameStart;
+ d->frameEnd = _frameEnd;
+ // Remember that setFrameStartEnd was called. This activates a slightly
+ // different mode (when moving start and end positions).
+ m_bFrameStartSet = true;
+ update();
+ }
+}
+
+void KoRuler::setRightIndent( double _right )
+{
+ d->i_right = makeIntern( _right );
+ update();
+}
+
+void KoRuler::setDirection( bool rtl )
+{
+ d->rtl = rtl;
+ update();
+}
+
+void KoRuler::changeFlags(int _flags)
+{
+ d->flags = _flags;
+}
+
+int KoRuler::flags() const
+{
+ return d->flags;
+}
+
+bool KoRuler::doubleClickedIndent() const
+{
+ return d->doubleClickedIndent;
+}
+
+double KoRuler::applyRtlAndZoom( double value ) const
+{
+ int frameWidth = d->frameEnd - frameStart;
+ return d->rtl ? ( frameWidth - zoomIt( value ) ) : zoomIt( value );
+}
+
+double KoRuler::unZoomItRtl( int pixValue ) const
+{
+ int frameWidth = d->frameEnd - frameStart;
+ return d->rtl ? ( unZoomIt( (double)(frameWidth - pixValue) ) ) : unZoomIt( (double)pixValue );
+}
+
+void KoRuler::slotMenuActivated( int i )
+{
+ if ( i >= 0 && i <= KoUnit::U_LASTUNIT )
+ {
+ KoUnit::Unit unit = static_cast<KoUnit::Unit>(i);
+ setUnit( unit );
+ emit unitChanged( unit );
+ }
+}
+
+QSize KoRuler::minimumSizeHint() const
+{
+ QSize size;
+ QFont font = KGlobalSettings::toolBarFont();
+ QFontMetrics fm( font );
+
+ size.setWidth( QMAX( fm.height() + 4, 20 ) );
+ size.setHeight( QMAX( fm.height() + 4, 20 ) );
+
+ return size;
+}
+
+QSize KoRuler::sizeHint() const
+{
+ return minimumSizeHint();
+}
+
+void KoRuler::setPageLayout( const KoPageLayout& _layout )
+{
+ d->layout = _layout;
+ update();
+}
+
+#include "KoRuler.moc"
diff --git a/lib/kofficeui/KoRuler.h b/lib/kofficeui/KoRuler.h
new file mode 100644
index 00000000..77d169f4
--- /dev/null
+++ b/lib/kofficeui/KoRuler.h
@@ -0,0 +1,372 @@
+/* This file is part of the KDE project
+ Copyright (C) 1998, 1999 Reginald Stadlbauer <reggie@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+// Description: Ruler (header)
+
+/******************************************************************/
+
+#ifndef koRuler_h
+#define koRuler_h
+
+#include <qframe.h>
+#include <qpixmap.h>
+
+#include <kdemacros.h>
+#include <koffice_export.h>
+#include <KoGlobal.h>
+#include <KoTabChooser.h>
+#include <KoUnit.h>
+
+class KoPageLayout;
+class QPainter;
+
+enum KoTabulators { T_LEFT = 0, T_CENTER = 1, T_RIGHT = 2, T_DEC_PNT = 3, T_INVALID = -1 };
+enum KoTabulatorFilling { TF_BLANK = 0, TF_DOTS = 1, TF_LINE = 2, TF_DASH = 3, TF_DASH_DOT = 4, TF_DASH_DOT_DOT = 5};
+
+/**
+ * Struct: KoTabulator
+ * Defines the position of a tabulation (in pt), and its type
+ */
+struct KoTabulator {
+ /**
+ * Position of the tab in pt
+ */
+ double ptPos;
+ /**
+ * Type of tab (left/center/right/decimalpoint)
+ */
+ KoTabulators type;
+ /**
+ * Type of tab filling.
+ */
+ KoTabulatorFilling filling;
+ /**
+ * Width of the tab filling line.
+ */
+ double ptWidth;
+ /**
+ * Alignment character.
+ */
+ QChar alignChar;
+
+ bool operator==( const KoTabulator & t ) const {
+ return QABS( ptPos - t.ptPos ) < 1E-4 && type == t.type &&
+ filling == t.filling && QABS( ptWidth - t.ptWidth ) < 1E-4;
+ }
+ bool operator!=( const KoTabulator & t ) const {
+ return !operator==(t);
+ }
+ // Operators used for sorting
+ bool operator < ( const KoTabulator & t ) const {
+ return ptPos < t.ptPos;
+ }
+ bool operator <= ( const KoTabulator & t ) const {
+ return ptPos <= t.ptPos;
+ }
+ bool operator > ( const KoTabulator & t ) const {
+ return ptPos > t.ptPos;
+ }
+};
+
+typedef QValueList<KoTabulator> KoTabulatorList;
+
+class KoRulerPrivate;
+
+/**
+ * KoRuler is the horizontal or vertical ruler, to be used around
+ * the drawing area of most KOffice programs.
+ *
+ * It shows the graduated ruler with numbering, in any of the base units (like mm/pt/inch),
+ * and supports zooming, tabulators, paragraph indents, showing the mouse position, etc.
+ *
+ * It also offers a popupmenu upon right-clicking, for changing the unit,
+ * the page layout, or removing a tab.
+ */
+class KOFFICEUI_EXPORT KoRuler : public QFrame
+{
+ Q_OBJECT
+ friend class KoRulerPrivate; // for the Action enum
+public:
+ static const int F_TABS;
+ static const int F_INDENTS;
+ static const int F_HELPLINES;
+ static const int F_NORESIZE;
+
+ /**
+ * Create a ruler
+ * TODO document params
+ */
+ KoRuler( QWidget *_parent, QWidget *_canvas, Orientation _orientation,
+ const KoPageLayout& _layout, int _flags, KoUnit::Unit _unit,
+ KoTabChooser *_tabChooser = 0L );
+ ~KoRuler();
+
+ /**
+ * Set the unit to be used. The unit is specified using text as defined in KoUnit, for
+ * example "mm", "pt" or "inch".
+ * @deprecated You should use the KoUnit::Unit variant instead.
+ */
+ void setUnit( const QString& unit ) KDE_DEPRECATED ;
+ /**
+ * Set the unit to be used.
+ */
+ void setUnit( KoUnit::Unit unit );
+
+ /**
+ * Set the zoom of the ruler (default value of 1.0 is 100%)
+ */
+ void setZoom( const double& zoom=1.0 );
+ /**
+ * @return the current zoom level
+ */
+ const double& zoom() const { return m_zoom; }
+
+ /**
+ * Set the page layout, see @ref KoPageLayout.
+ * This defines the size of the page and the margins,
+ * from which the size of the ruler is deducted.
+ */
+ void setPageLayout( const KoPageLayout& _layout );
+
+ /**
+ * Call showMousePos(true) if the ruler should indicate the position
+ * of the mouse. This is usually only the case for drawing applications,
+ * so it is not enabled by default.
+ */
+ void showMousePos( bool _showMPos );
+ /**
+ * Set the position of the mouse, to update the indication in the ruler.
+ * This is only effective if showMousePos(true) was called previously.
+ * The position to give is not zoomed, it's in real pixel coordinates!
+ */
+ void setMousePos( int mx, int my );
+
+ /**
+ * Set a global offset to the X and Y coordinates.
+ * Usually the main drawing area is a QScrollView, and this is called
+ * with contentsX() and contentsY(), each time those values change.
+ */
+ void setOffset( int _diffx, int _diffy );
+
+ /**
+ * Set the [paragraph] left indent to the specified position (in the current unit)
+ */
+ void setLeftIndent( double _left )
+ { i_left = makeIntern( _left ); update(); }
+
+ /**
+ * Set the [paragraph] first-line left indent to the specified position (in the current unit)
+ * This indent is cumulated with the left or right margin, depending on the [paragraph] direction.
+ */
+ void setFirstIndent( double _first )
+ { i_first = makeIntern( _first ); update(); }
+
+ /**
+ * Set the [paragraph] right indent to the specified position (in the current unit)
+ */
+ void setRightIndent( double _right );
+
+ /**
+ * Set the [paragraph] direction. By default (rtl=false), the left indent is on the
+ * left, and the right indent is on the right ;)
+ * If rtl=true, it's the opposite.
+ */
+ void setDirection( bool rtl );
+
+ /**
+ * Set the list of tabulators to show in the ruler.
+ */
+ void setTabList( const KoTabulatorList & tabList );
+
+ /**
+ * Set the start and the end of the current 'frame', i.e. the part
+ * of the page in which we are currently working. See KWord frames
+ * for an example where this is used. The tab positions and paragraph
+ * indents then become relative to the beginning of the frame, and the
+ * ruler goes from frameStart to frameEnd instead of using the page margins.
+ * @p _frameStart et @p _frameEnd are in pixel coordinates.
+ */
+ void setFrameStartEnd( int _frameStart, int _frameEnd );
+
+ /**
+ * KoRuler is in "read write" mode by default.
+ * Use setReadWrite(false) to use it in read-only mode.
+ */
+ void setReadWrite( bool _readWrite );
+
+ /**
+ * Change the flag (i.e. activate or deactivate certain features of KoRuler)
+ */
+ void changeFlags(int _flags);
+
+ /**
+ * Set the size of the grid used for tabs positioning, size in pt.
+ * default value is 0. 0 means no grid.
+ */
+ void setGridSize(double newGridSize) { gridSize=newGridSize; }
+
+ /**
+ * @return the current flags
+ */
+ int flags() const;
+
+ /**
+ * @return whether the current doubleClicked() signal was triggered
+ * by the user double-clicking on an indent (BCI). It returns false
+ * if the user just double-clicked on an "empty" part of the ruler.
+ *
+ * This method is strictly provided for use in a slot connected to the
+ * doubleClicked() signal; calling it at any other time results in
+ * undefined behavior.
+ */
+ bool doubleClickedIndent() const;
+
+ /**
+ * Enable or disable the "Page Layout" menu item.
+ */
+ void setPageLayoutMenuItemEnabled(bool b);
+
+ /**
+ * Reimplemented from QWidget
+ */
+ virtual QSize minimumSizeHint() const;
+
+ /**
+ * Reimplemented from QWidget
+ */
+ virtual QSize sizeHint() const;
+
+signals:
+ void newPageLayout( const KoPageLayout & );
+ void newLeftIndent( double );
+ void newFirstIndent( double );
+ void newRightIndent( double );
+ /** Old signal, kept for compatibility. Use doubleClicked instead. */
+ void openPageLayoutDia();
+ /** This signal is emitted when double-clicking the ruler (or an indent) */
+ void doubleClicked();
+ /** This signal is emitted when double-clicking a tab */
+ void doubleClicked( double ptPos );
+
+ void tabListChanged( const KoTabulatorList & );
+ void unitChanged( KoUnit::Unit );
+
+ void addGuide(const QPoint &, bool, int );
+ void moveGuide( const QPoint &, bool, int );
+ void addHelpline(const QPoint &, bool );
+ void moveHelpLines( const QPoint &, bool );
+
+protected:
+ enum Action {A_NONE, A_BR_LEFT, A_BR_RIGHT, A_BR_TOP, A_BR_BOTTOM,
+ A_LEFT_INDENT, A_FIRST_INDENT, A_TAB, A_RIGHT_INDENT,
+ A_HELPLINES };
+
+ void drawContents( QPainter *_painter )
+ { orientation == Qt::Horizontal ? drawHorizontal( _painter ) : drawVertical( _painter ); }
+
+ void drawHorizontal( QPainter *_painter );
+ void drawVertical( QPainter *_painter );
+ void drawTabs( QPainter &_painter );
+
+ void mousePressEvent( QMouseEvent *e );
+ void mouseReleaseEvent( QMouseEvent *e );
+ void mouseMoveEvent( QMouseEvent *e );
+ void mouseDoubleClickEvent( QMouseEvent* );
+ void resizeEvent( QResizeEvent *e );
+ void handleDoubleClick();
+
+ double makeIntern( double _v );
+ double zoomIt(const double &value) const;
+ int zoomIt(const int &value) const;
+ unsigned int zoomIt(const unsigned int &value) const;
+ double unZoomIt(const double &value) const;
+ int unZoomIt(const int &value) const;
+ unsigned int unZoomIt(const unsigned int &value) const;
+ void setupMenu();
+ void uncheckMenu();
+ void searchTab(int mx);
+ void drawLine(int oldX, int newX);
+
+private:
+ double applyRtlAndZoom( double value ) const;
+ double unZoomItRtl( int pixValue ) const;
+ double lineDistance() const;
+ bool willRemoveTab( int y ) const;
+
+ KoRulerPrivate *d;
+
+ Qt::Orientation orientation;
+ int diffx, diffy;
+ double i_left, i_first;
+ QPixmap buffer;
+ double m_zoom, m_1_zoom;
+ KoUnit::Unit m_unit;
+ bool hasToDelete;
+ bool showMPos;
+ bool m_bFrameStartSet;
+ bool m_bReadWrite;
+ int mposX, mposY;
+ int frameStart;
+
+ double gridSize;
+
+protected slots:
+ void slotMenuActivated( int i );
+ void pageLayoutDia() { emit doubleClicked()/*openPageLayoutDia()*/; }
+ void rbRemoveTab();
+
+};
+
+inline double KoRuler::zoomIt(const double &value) const {
+ if (m_zoom==1.0)
+ return value;
+ return m_zoom*value;
+}
+
+inline int KoRuler::zoomIt(const int &value) const {
+ if (m_zoom==1.0)
+ return value;
+ return qRound(m_zoom*value);
+}
+
+inline unsigned int KoRuler::zoomIt(const unsigned int &value) const {
+ if (m_zoom==1.0)
+ return value;
+ return static_cast<unsigned int>(qRound(m_zoom*value));
+}
+
+inline double KoRuler::unZoomIt(const double &value) const {
+ if(m_zoom==1.0)
+ return value;
+ return value*m_1_zoom;
+}
+
+inline int KoRuler::unZoomIt(const int &value) const {
+ if(m_zoom==1.0)
+ return value;
+ return qRound(value*m_1_zoom);
+}
+
+inline unsigned int KoRuler::unZoomIt(const unsigned int &value) const {
+ if(m_zoom==1.0)
+ return value;
+ return static_cast<unsigned int>(qRound(value*m_1_zoom));
+}
+
+#endif
diff --git a/lib/kofficeui/KoSelectAction.cpp b/lib/kofficeui/KoSelectAction.cpp
new file mode 100644
index 00000000..68237b6a
--- /dev/null
+++ b/lib/kofficeui/KoSelectAction.cpp
@@ -0,0 +1,193 @@
+/* This file is part of the KDE project
+ Copyright (C) 2004 Peter Simonsson <psn@linux.se>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#include "KoSelectAction.h"
+
+#include <qpixmap.h>
+#include <qbitmap.h>
+#include <qwhatsthis.h>
+#include <qmenubar.h>
+
+#include <kpopupmenu.h>
+#include <kapplication.h>
+#include <kdebug.h>
+#include <ktoolbar.h>
+#include <ktoolbarbutton.h>
+#include <kiconloader.h>
+#include <klocale.h>
+
+class KoSelectAction::KoSelectActionPrivate
+{
+ public:
+ KoSelectActionPrivate()
+ {
+ m_popup = new KPopupMenu(0L,"KoLineStyleAction::popup");
+ m_currentSelection = 0;
+ }
+
+ ~KoSelectActionPrivate()
+ {
+ delete m_popup;
+ m_popup = 0;
+ }
+
+ KPopupMenu* m_popup;
+ int m_currentSelection;
+};
+
+KoSelectAction::KoSelectAction(const QString &text, const QString& icon,
+ QObject* parent, const char* name) : KAction(text, icon, 0, parent, name)
+{
+ d = new KoSelectActionPrivate;
+ setShowCurrentSelection(true);
+
+ connect(popupMenu(), SIGNAL(activated(int)), this, SLOT(execute(int)));
+}
+
+KoSelectAction::KoSelectAction(const QString &text, const QString& icon, const QObject* receiver,
+ const char* slot, QObject* parent, const char* name) : KAction(text, icon, 0, parent, name)
+{
+ d = new KoSelectActionPrivate;
+
+ connect(this, SIGNAL(selectionChanged(int)), receiver, slot);
+ connect(popupMenu(), SIGNAL(activated(int)), this, SLOT(execute(int)));
+}
+
+KoSelectAction::~KoSelectAction()
+{
+ delete d;
+}
+
+KPopupMenu* KoSelectAction::popupMenu() const
+{
+ return d->m_popup;
+}
+
+void KoSelectAction::popup(const QPoint& global)
+{
+ popupMenu()->popup(global);
+}
+
+int KoSelectAction::plug(QWidget* widget, int index)
+{
+ // This function is copied from KActionMenu::plug
+ if (kapp && !kapp->authorizeKAction(name()))
+ return -1;
+ kdDebug(129) << "KAction::plug( " << widget << ", " << index << " )" << endl; // remove -- ellis
+ if ( widget->inherits("QPopupMenu") )
+ {
+ QPopupMenu* menu = static_cast<QPopupMenu*>( widget );
+ int id;
+
+ if ( hasIconSet() )
+ id = menu->insertItem( iconSet(), text(), popupMenu(), -1, index );
+ else
+ id = menu->insertItem( kapp->iconLoader()->loadIcon(icon(), KIcon::Small),
+ text(), popupMenu(), -1, index );
+
+ if ( !isEnabled() )
+ menu->setItemEnabled( id, false );
+
+ addContainer( menu, id );
+ connect( menu, SIGNAL( destroyed() ), this, SLOT( slotDestroyed() ) );
+
+ return containerCount() - 1;
+ }
+ else if ( widget->inherits( "KToolBar" ) )
+ {
+ KToolBar *bar = static_cast<KToolBar *>( widget );
+
+ int id_ = KAction::getToolButtonID();
+
+ if ( icon().isEmpty() && !iconSet().isNull() ) {
+ bar->insertButton( iconSet().pixmap(), id_, SIGNAL( clicked() ), this,
+ SLOT( slotActivated() ), isEnabled(), plainText(),
+ index );
+ } else {
+ KInstance *instance;
+
+ if ( m_parentCollection ) {
+ instance = m_parentCollection->instance();
+ } else {
+ instance = KGlobal::instance();
+ }
+
+ bar->insertButton( icon(), id_, SIGNAL( clicked() ), this,
+ SLOT( slotActivated() ), isEnabled(), plainText(),
+ index, instance );
+ }
+
+ addContainer( bar, id_ );
+
+ if (!whatsThis().isEmpty())
+ QWhatsThis::add( bar->getButton(id_), whatsThis() );
+
+ connect( bar, SIGNAL( destroyed() ), this, SLOT( slotDestroyed() ) );
+
+ bar->getButton(id_)->setPopup(popupMenu(), true );
+
+ return containerCount() - 1;
+ }
+ else if ( widget->inherits( "QMenuBar" ) )
+ {
+ QMenuBar *bar = static_cast<QMenuBar *>( widget );
+
+ int id;
+
+ id = bar->insertItem( text(), popupMenu(), -1, index );
+
+ if ( !isEnabled() )
+ bar->setItemEnabled( id, false );
+
+ addContainer( bar, id );
+ connect( bar, SIGNAL( destroyed() ), this, SLOT( slotDestroyed() ) );
+
+ return containerCount() - 1;
+ }
+
+ return -1;
+}
+
+void KoSelectAction::execute(int index)
+{
+ setCurrentSelection(index);
+ emit selectionChanged(d->m_currentSelection);
+}
+
+int KoSelectAction::currentSelection()
+{
+ return d->m_currentSelection;
+}
+
+void KoSelectAction::setCurrentSelection(int index)
+{
+ if(popupMenu()->isCheckable()) {
+ popupMenu()->setItemChecked(d->m_currentSelection, false);
+ popupMenu()->setItemChecked(index, true);
+ }
+
+ d->m_currentSelection = index;
+}
+
+void KoSelectAction::setShowCurrentSelection(bool show)
+{
+ popupMenu()->setCheckable(show);
+}
+
+#include "KoSelectAction.moc"
diff --git a/lib/kofficeui/KoSelectAction.h b/lib/kofficeui/KoSelectAction.h
new file mode 100644
index 00000000..6cdae7c4
--- /dev/null
+++ b/lib/kofficeui/KoSelectAction.h
@@ -0,0 +1,90 @@
+/* This file is part of the KDE project
+ Copyright (C) 2004 Peter Simonsson <psn@linux.se>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+#ifndef KOSELECTACTION_H
+#define KOSELECTACTION_H
+
+#include <kaction.h>
+#include <koffice_export.h>
+class KPopupMenu;
+class QPoint;
+
+/** An action that provides a menu with items that can be selected.
+ * The main difference between this action and a KSelectAction is that
+ * it is plugged into a toolbar as a dropdown menu and not as a combobox.
+ */
+class KOFFICEUI_EXPORT KoSelectAction : public KAction
+{
+ Q_OBJECT
+ public:
+ /** Constructs a KoSelectAction with a text and an icon.
+ * @param text The text that will be displayed.
+ * @param icon The dynamically loaded icon that goes with this action.
+ * @param parent This action's parent.
+ * @param name An internal name for this action.
+ */
+ KoSelectAction(const QString& text, const QString& icon, QObject* parent = 0, const char* name = 0);
+ /** Same as above, but it also connects a slot to the selectionChanged(int) signal.
+ * @param text The text that will be displayed.
+ * @param icon The dynamically loaded icon that goes with this action.
+ * @param receiver The SLOT's parent.
+ * @param slot The SLOT to invoke when a selectionChanged(int) signal is emited.
+ * @param parent This action's parent.
+ * @param name An internal name for this action.
+ */
+ KoSelectAction(const QString& text, const QString& icon, const QObject* receiver,
+ const char* slot, QObject* parent, const char* name = 0);
+ ~KoSelectAction();
+
+ /** Returns a pointer to the popup menu. */
+ KPopupMenu* popupMenu() const;
+ /** Shows the popup menu.
+ * @param global Position at which the popup menu is shown.
+ */
+ void popup(const QPoint& global);
+
+ virtual int plug(QWidget* widget, int index = -1);
+
+ /** Returns the index of the currently selected item. */
+ virtual int currentSelection();
+
+ /** If the current selection selection should be shown or not in the menu */
+ void setShowCurrentSelection(bool show);
+
+ signals:
+ /** Emited when the selection changed */
+ void selectionChanged(int);
+
+ public slots:
+ /** Set which item that should be selected.
+ * @param index Index of item that should be selected
+ */
+ virtual void setCurrentSelection(int index);
+
+ protected slots:
+ /** Execute an item. By default it sets the item as selected and emits the selectionChanged signal.
+ * @param index Index of the item that should be executed.
+ */
+ virtual void execute(int index);
+
+ private:
+ class KoSelectActionPrivate;
+ KoSelectActionPrivate* d;
+};
+
+#endif
diff --git a/lib/kofficeui/KoTabBar.cpp b/lib/kofficeui/KoTabBar.cpp
new file mode 100644
index 00000000..d73025b4
--- /dev/null
+++ b/lib/kofficeui/KoTabBar.cpp
@@ -0,0 +1,913 @@
+/* This file is part of the KDE project
+ Copyright (C) 2003 Ariya Hidayat <ariya@kde.org>
+ Copyright (C) 2003 Norbert Andres <nandres@web.de>
+ Copyright (C) 2002 Laurent Montel <montel@kde.org>
+ Copyright (C) 1999 David Faure <faure@kde.org>
+ Copyright (C) 1999 Boris Wedl <boris.wedl@kfunigraz.ac.at>
+ Copyright (C) 1998-2000 Torben Weis <weis@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#include "KoTabBar.h"
+
+#include <qdrawutil.h>
+#include <qpainter.h>
+#include <qstring.h>
+#include <qstringlist.h>
+#include <qstyle.h>
+#include <qtimer.h>
+#include <qtoolbutton.h>
+#include <qvaluevector.h>
+#include <qwidget.h>
+
+// TODO
+// improvement possibilities
+// - use offscreen buffer to reduce flicker even more
+// - keep track of tabs, only (re)layout when necessary
+// - paint all tabs to buffer, show only by shifting
+// - customizable button pixmaps
+// - use QStyle to paint the tabs & buttons (is it good/possible?)
+
+
+class KoTabBarPrivate
+{
+public:
+ KoTabBar* tabbar;
+
+ // scroll buttons
+ QToolButton* scrollFirstButton;
+ QToolButton* scrollLastButton;
+ QToolButton* scrollBackButton;
+ QToolButton* scrollForwardButton;
+
+ // read-only: no mouse drag, double-click, right-click
+ bool readOnly;
+
+ // if true, layout is from right to left
+ bool reverseLayout;
+
+ // list of all tabs, in order of appearance
+ QStringList tabs;
+
+ // array of QRect for each visible tabs
+ QValueVector<QRect> tabRects;
+
+ // leftmost tab (or rightmost if reverseLayout)
+ int firstTab;
+
+ // rightmost tab (or leftmost if reverseLayout)
+ int lastTab;
+
+ // the active tab in the range form 1..n.
+ // if this value is 0, that means that no tab is active.
+ int activeTab;
+
+ // unusable space on the left, taken by the scroll buttons
+ int offset;
+
+ // when the user drag the tab (in order to move it)
+ // this is the target position, it's 0 if no tab is dragged
+ int targetTab;
+
+ // wheel movement since selected tab was last changed by the
+ // mouse wheel
+ int wheelDelta;
+
+ // true if autoscroll is active
+ bool autoScroll;
+
+ // calculate the bounding rectangle for each visible tab
+ void layoutTabs();
+
+ // reposition scroll buttons
+ void layoutButtons();
+
+ // find a tab whose bounding rectangle contains the pos
+ // return -1 if no such tab is found
+ int tabAt( const QPoint& pos );
+
+ // draw a single tab
+ void drawTab( QPainter& painter, QRect& rect, const QString& text, bool active );
+
+ // draw a marker to indicate tab moving
+ void drawMoveMarker( QPainter& painter, int x, int y );
+
+ // update the enable/disable status of scroll buttons
+ void updateButtons();
+
+};
+
+// built-in pixmap for scroll-first button
+static const char * arrow_leftmost_xpm[] = {
+"10 10 2 1",
+" c None",
+". c #000000",
+" ",
+" . . ",
+" . .. ",
+" . ... ",
+" . .... ",
+" . ... ",
+" . .. ",
+" . . ",
+" ",
+" "};
+
+// built-in pixmap for scroll-last button
+static const char * arrow_rightmost_xpm[] = {
+"10 10 2 1",
+" c None",
+". c #000000",
+" ",
+" . . ",
+" .. . ",
+" ... . ",
+" .... . ",
+" ... . ",
+" .. . ",
+" . . ",
+" ",
+" "};
+
+// built-in pixmap for scroll-left button
+static const char * arrow_left_xpm[] = {
+"10 10 2 1",
+" c None",
+". c #000000",
+" ",
+" . ",
+" .. ",
+" ... ",
+" .... ",
+" ... ",
+" .. ",
+" . ",
+" ",
+" "};
+
+// built-in pixmap for scroll-right button
+static const char * arrow_right_xpm[] = {
+"10 10 2 1",
+" c None",
+". c #000000",
+" ",
+" . ",
+" .. ",
+" ... ",
+" .... ",
+" ... ",
+" .. ",
+" . ",
+" ",
+" "};
+
+
+void KoTabBarPrivate::layoutTabs()
+{
+ tabRects.clear();
+
+ QPainter painter( tabbar );
+
+ QFont f = painter.font();
+ f.setBold( true );
+ painter.setFont( f );
+ QFontMetrics fm = painter.fontMetrics();
+
+ if( !reverseLayout )
+ {
+ // left to right
+ int x = 0;
+ for( unsigned c = 0; c < tabs.count(); c++ )
+ {
+ QRect rect;
+ if( (int)c >= firstTab-1 )
+ {
+ QString text = tabs[ c ];
+ int tw = fm.width( text ) + 4;
+ rect = QRect( x, 0, tw + 20, tabbar->height() );
+ x = x + tw + 20;
+ }
+ tabRects.append( rect );
+ }
+
+ lastTab = tabRects.count();
+ for( unsigned i = 0; i < tabRects.count(); i++ )
+ if( tabRects[i].right()-10+offset > tabbar->width() )
+ {
+ lastTab = i;
+ break;
+ }
+ }
+ else
+ {
+ // right to left
+ int x = tabbar->width() - offset;
+ for( unsigned c = 0; c < tabs.count(); c++ )
+ {
+ QRect rect;
+ if( (int)c >= firstTab-1 )
+ {
+ QString text = tabs[ c ];
+ int tw = fm.width( text ) + 4;
+ rect = QRect( x - tw - 20, 0, tw + 20, tabbar->height() );
+ x = x - tw - 20;
+ }
+ tabRects.append( rect );
+ }
+
+ lastTab = tabRects.count();
+ for( unsigned i = tabRects.count()-1; i>0; i-- )
+ if( tabRects[i].left() > 0 )
+ {
+ lastTab = i+1;
+ break;
+ }
+ }
+}
+
+int KoTabBarPrivate::tabAt( const QPoint& pos )
+{
+ for( unsigned i = 0; i < tabRects.count(); i++ )
+ {
+ QRect rect = tabRects[ i ];
+ if( rect.isNull() ) continue;
+ if( rect.contains( pos ) ) return i;
+ }
+
+ return -1; // not found
+}
+
+void KoTabBarPrivate::drawTab( QPainter& painter, QRect& rect, const QString& text, bool active )
+{
+ QPointArray polygon;
+
+ if( !reverseLayout )
+ polygon.setPoints( 6, rect.x(), rect.y(),
+ rect.x(), rect.bottom()-3,
+ rect.x()+2, rect.bottom(),
+ rect.right()-4, rect.bottom(),
+ rect.right()-2, rect.bottom()-2,
+ rect.right()+5, rect.top() );
+ else
+ polygon.setPoints( 6, rect.right(), rect.top(),
+ rect.right(), rect.bottom()-3,
+ rect.right()-2, rect.bottom(),
+ rect.x()+4, rect.bottom(),
+ rect.x()+2, rect.bottom()-2,
+ rect.x()-5, rect.top() );
+
+ painter.save();
+
+ // fill it first
+ QBrush bg = tabbar->colorGroup().background();
+ if( active ) bg = tabbar->colorGroup().base();
+ painter.setBrush( bg );
+ painter.setPen( QPen( Qt::NoPen ) );
+ painter.drawPolygon( polygon );
+
+ // draw the lines
+ painter.setPen( tabbar->colorGroup().dark() );
+ if( !active )
+ painter.drawLine( rect.x()-25, rect.y(), rect.right()+25, rect.top() );
+ // Qt4: painter.setRenderHint( QPainter::Antialiasing );
+ painter.drawPolyline( polygon );
+
+ painter.setPen( tabbar->colorGroup().buttonText() );
+ QFont f = painter.font();
+ if( active ) f.setBold( true );
+ painter.setFont( f );
+ QFontMetrics fm = painter.fontMetrics();
+ int tx = rect.x() + ( rect.width() - fm.width( text ) ) / 2;
+ int ty = rect.y() + ( rect.height() - fm.height() ) / 2 + fm.ascent();
+ painter.drawText( tx, ty, text );
+
+ painter.restore();
+}
+
+void KoTabBarPrivate::drawMoveMarker( QPainter& painter, int x, int y )
+{
+ QPointArray movmark;
+ movmark.setPoints( 3, x, y, x + 7, y, x + 4, y + 6);
+ QBrush oldBrush = painter.brush();
+ painter.setBrush( Qt::black );
+ painter.drawPolygon(movmark);
+ painter.setBrush( oldBrush );
+}
+
+void KoTabBarPrivate::layoutButtons()
+{
+ int bw = tabbar->height();
+ int w = tabbar->width();
+ offset = bw * 4;
+
+ if( !reverseLayout )
+ {
+ scrollFirstButton->setGeometry( 0, 0, bw, bw );
+ scrollFirstButton->setPixmap( arrow_leftmost_xpm );
+ scrollBackButton->setGeometry( bw, 0, bw, bw );
+ scrollBackButton->setPixmap( arrow_left_xpm );
+ scrollForwardButton->setGeometry( bw*2, 0, bw, bw );
+ scrollForwardButton->setPixmap( arrow_right_xpm );
+ scrollLastButton->setGeometry( bw*3, 0, bw, bw );
+ scrollLastButton->setPixmap( arrow_rightmost_xpm );
+ }
+ else
+ {
+ scrollFirstButton->setGeometry( w-bw, 0, bw, bw );
+ scrollFirstButton->setPixmap( arrow_rightmost_xpm );
+ scrollBackButton->setGeometry( w-2*bw, 0, bw, bw );
+ scrollBackButton->setPixmap( arrow_right_xpm );
+ scrollForwardButton->setGeometry( w-3*bw, 0, bw, bw );
+ scrollForwardButton->setPixmap( arrow_left_xpm );
+ scrollLastButton->setGeometry( w-4*bw, 0, bw, bw );
+ scrollLastButton->setPixmap( arrow_leftmost_xpm );
+ }
+ }
+
+void KoTabBarPrivate::updateButtons()
+{
+ scrollFirstButton->setEnabled( tabbar->canScrollBack() );
+ scrollBackButton->setEnabled( tabbar->canScrollBack() );
+ scrollForwardButton->setEnabled( tabbar->canScrollForward() );
+ scrollLastButton->setEnabled( tabbar->canScrollForward() );
+}
+
+// creates a new tabbar
+KoTabBar::KoTabBar( QWidget* parent, const char* name )
+ : QWidget( parent, name, Qt::WResizeNoErase | Qt::WRepaintNoErase )
+{
+ d = new KoTabBarPrivate;
+ d->tabbar = this;
+ d->readOnly = false;
+ d->reverseLayout = false;
+ d->firstTab = 1;
+ d->lastTab = 0;
+ d->activeTab = 0;
+ d->targetTab = 0;
+ d->wheelDelta = 0;
+ d->autoScroll = false;
+ d->offset = 64;
+
+ // initialize the scroll buttons
+ d->scrollFirstButton = new QToolButton( this );
+ connect( d->scrollFirstButton, SIGNAL( clicked() ),
+ this, SLOT( scrollFirst() ) );
+ d->scrollLastButton = new QToolButton( this );
+ connect( d->scrollLastButton, SIGNAL( clicked() ),
+ this, SLOT( scrollLast() ) );
+ d->scrollBackButton = new QToolButton( this );
+ connect( d->scrollBackButton, SIGNAL( clicked() ),
+ this, SLOT( scrollBack() ) );
+ d->scrollForwardButton = new QToolButton( this );
+ connect( d->scrollForwardButton, SIGNAL( clicked() ),
+ this, SLOT( scrollForward() ) );
+ d->layoutButtons();
+ d->updateButtons();
+}
+
+// destroys the tabbar
+KoTabBar::~KoTabBar()
+{
+ delete d;
+}
+
+// adds a new visible tab
+void KoTabBar::addTab( const QString& text )
+{
+ d->tabs.append( text );
+
+ update();
+}
+
+// removes a tab
+void KoTabBar::removeTab( const QString& text )
+{
+ int i = d->tabs.findIndex( text );
+ if ( i == -1 ) return;
+
+ if ( d->activeTab == i + 1 )
+ d->activeTab = 0;
+
+ d->tabs.remove( text );
+
+ update();
+}
+
+// removes all tabs
+void KoTabBar::clear()
+{
+ d->tabs.clear();
+ d->activeTab = 0;
+ d->firstTab = 1;
+
+ update();
+}
+
+bool KoTabBar::readOnly() const
+{
+ return d->readOnly;
+}
+
+void KoTabBar::setReadOnly( bool ro )
+{
+ d->readOnly = ro;
+}
+
+bool KoTabBar::reverseLayout() const
+{
+ return d->reverseLayout;
+}
+
+void KoTabBar::setReverseLayout( bool reverse )
+{
+ if( reverse != d->reverseLayout )
+ {
+ d->reverseLayout = reverse;
+ d->layoutTabs();
+ d->layoutButtons();
+ d->updateButtons();
+ update();
+ }
+}
+
+void KoTabBar::setTabs( const QStringList& list )
+{
+ QString left, active;
+
+ if( d->activeTab > 0 )
+ active = d->tabs[ d->activeTab-1 ];
+ if( d->firstTab > 0 )
+ left = d->tabs[ d->firstTab-1 ];
+
+ d->tabs = list;
+
+ if( !left.isNull() )
+ {
+ d->firstTab = d->tabs.findIndex( left ) + 1;
+ if( d->firstTab > (int)d->tabs.count() )
+ d->firstTab = 1;
+ if( d->firstTab <= 0 )
+ d->firstTab = 1;
+ }
+
+ d->activeTab = 0;
+ if( !active.isNull() )
+ setActiveTab( active );
+
+ update();
+}
+
+QStringList KoTabBar::tabs() const
+{
+ return d->tabs;
+}
+
+unsigned KoTabBar::count() const
+{
+ return d->tabs.count();
+}
+
+bool KoTabBar::canScrollBack() const
+{
+ if ( d->tabs.count() == 0 )
+ return false;
+
+ return d->firstTab > 1;
+}
+
+bool KoTabBar::canScrollForward() const
+{
+ if ( d->tabs.count() == 0 )
+ return false;
+
+ return d->lastTab < (int)d->tabs.count();
+}
+
+void KoTabBar::scrollBack()
+{
+ if ( !canScrollBack() )
+ return;
+
+ d->firstTab--;
+ if( d->firstTab < 1 ) d->firstTab = 1;
+
+ d->layoutTabs();
+ d->updateButtons();
+ update();
+}
+
+void KoTabBar::scrollForward()
+{
+ if ( !canScrollForward() )
+ return;
+
+ d->firstTab ++;
+ if( d->firstTab > (int)d->tabs.count() )
+ d->firstTab = d->tabs.count();
+
+ d->layoutTabs();
+ d->updateButtons();
+ update();
+}
+
+void KoTabBar::scrollFirst()
+{
+ if ( !canScrollBack() )
+ return;
+
+ d->firstTab = 1;
+ d->layoutTabs();
+ d->updateButtons();
+ update();
+}
+
+void KoTabBar::scrollLast()
+{
+ if ( !canScrollForward() )
+ return;
+
+ d->layoutTabs();
+
+ if( !d->reverseLayout )
+ {
+ int fullWidth = d->tabRects[ d->tabRects.count()-1 ].right();
+ int delta = fullWidth - width() + d->offset;
+ for( unsigned i = 0; i < d->tabRects.count(); i++ )
+ if( d->tabRects[i].x() > delta )
+ {
+ d->firstTab = i+1;
+ break;
+ }
+ }
+ else
+ {
+ // FIXME optimize this, perhaps without loop
+ for( ; d->firstTab <= (int)d->tabRects.count();)
+ {
+ int x = d->tabRects[ d->tabRects.count()-1 ].x();
+ if( x > 0 ) break;
+ d->firstTab++;
+ d->layoutTabs();
+ }
+ }
+
+ d->layoutTabs();
+ d->updateButtons();
+ update();
+}
+
+void KoTabBar::ensureVisible( const QString& tab )
+{
+ int i = d->tabs.findIndex( tab );
+ if ( i == -1 )
+ return;
+ i++;
+
+ // already visible, then do nothing
+ if( ( i >= d->firstTab ) && ( i <= d->lastTab ) )
+ return;
+
+ if( i < d->firstTab )
+ while( i < d->firstTab )
+ scrollBack();
+
+ if( i > d->lastTab )
+ while( i > d->lastTab )
+ scrollForward();
+}
+
+void KoTabBar::moveTab( unsigned tab, unsigned target )
+{
+ QString tabName = d->tabs[ tab ];
+ QStringList::Iterator it;
+
+ it = d->tabs.at( tab );
+ d->tabs.remove( it );
+
+ if( target > tab ) target--;
+ it = d->tabs.at( target );
+ if( target >= d->tabs.count() )
+ it = d->tabs.end();
+ d->tabs.insert( it, tabName );
+
+ if( d->activeTab == (int)tab+1 )
+ d->activeTab = target+1;
+
+ update();
+}
+
+void KoTabBar::setActiveTab( const QString& text )
+{
+ int i = d->tabs.findIndex( text );
+ if ( i == -1 )
+ return;
+
+ if ( i + 1 == d->activeTab )
+ return;
+
+ d->activeTab = i + 1;
+ d->updateButtons();
+ update();
+
+ emit tabChanged( text );
+}
+
+void KoTabBar::autoScrollBack()
+{
+ if( !d->autoScroll ) return;
+
+ scrollBack();
+
+ if( !canScrollBack() )
+ d->autoScroll = false;
+ else
+ QTimer::singleShot( 400, this, SLOT( autoScrollBack() ) );
+}
+
+void KoTabBar::autoScrollForward()
+{
+ if( !d->autoScroll ) return;
+
+ scrollForward();
+
+ if( !canScrollForward() )
+ d->autoScroll = false;
+ else
+ QTimer::singleShot( 400, this, SLOT( autoScrollForward() ) );
+}
+
+void KoTabBar::paintEvent( QPaintEvent* )
+{
+ if ( d->tabs.count() == 0 )
+ {
+ erase();
+ return;
+ }
+
+ QPainter painter;
+ QPixmap pm( size() );
+ pm.fill( colorGroup().background() );
+ painter.begin( &pm, this );
+
+ painter.setPen( colorGroup().dark() );
+ painter.drawLine( 0, 0, width(), 0 );
+
+ if( !d->reverseLayout )
+ painter.translate( 5, 0 );
+
+ d->layoutTabs();
+ d->updateButtons();
+
+ // draw first all non-active, visible tabs
+ for( int c = d->tabRects.count()-1; c>=0; c-- )
+ {
+ QRect rect = d->tabRects[ c ];
+ if( rect.isNull() ) continue;
+ QString text = d->tabs[ c ];
+ d->drawTab( painter, rect, text, false );
+ }
+
+ // draw the active tab
+ if( d->activeTab > 0 )
+ {
+ QRect rect = d->tabRects[ d->activeTab-1 ];
+ if( !rect.isNull() )
+ {
+ QString text = d->tabs[ d->activeTab-1 ];
+ d->drawTab( painter, rect, text, true );
+ }
+ }
+
+ // draw the move marker
+ if( d->targetTab > 0 )
+ {
+ int p = QMIN( d->targetTab, (int)d->tabRects.count() );
+ QRect rect = d->tabRects[ p-1 ];
+ if( !rect.isNull() )
+ {
+ int x = !d->reverseLayout ? rect.x() : rect.right()-7;
+ if( d->targetTab > (int)d->tabRects.count() )
+ x = !d->reverseLayout ? rect.right()-7 : rect.x()-3;
+ d->drawMoveMarker( painter, x, rect.y() );
+ }
+ }
+
+ painter.end();
+
+ if( !d->reverseLayout )
+ bitBlt( this, d->offset, 0, &pm );
+ else
+ bitBlt( this, 0, 0, &pm );
+
+}
+
+void KoTabBar::resizeEvent( QResizeEvent* )
+{
+ d->layoutButtons();
+ d->updateButtons();
+ update();
+}
+
+QSize KoTabBar::sizeHint() const
+{
+ return QSize( 40, style().pixelMetric( QStyle::PM_ScrollBarExtent, this ) );
+}
+
+void KoTabBar::renameTab( const QString& old_name, const QString& new_name )
+{
+ QStringList::Iterator it = d->tabs.find( old_name );
+ (*it) = new_name;
+
+ update();
+}
+
+QString KoTabBar::activeTab() const
+{
+ if( d->activeTab == 0 )
+ return QString::null;
+ else
+ return d->tabs[ d->activeTab ];
+}
+
+void KoTabBar::mousePressEvent( QMouseEvent* ev )
+{
+ if ( d->tabs.count() == 0 )
+ {
+ erase();
+ return;
+ }
+
+ d->layoutTabs();
+
+ QPoint pos = ev->pos();
+ if( !d->reverseLayout ) pos = pos - QPoint( d->offset,0 );
+
+ int tab = d->tabAt( pos ) + 1;
+ if( ( tab > 0 ) && ( tab != d->activeTab ) )
+ {
+ d->activeTab = tab;
+ update();
+
+ emit tabChanged( d->tabs[ d->activeTab-1] );
+
+ // scroll if partially visible
+ if( d->tabRects[ tab-1 ].right() > width() - d->offset )
+ scrollForward();
+ }
+
+ if( ev->button() == RightButton )
+ if( !d->readOnly )
+ emit contextMenu( ev->globalPos() );
+}
+
+void KoTabBar::mouseReleaseEvent( QMouseEvent* ev )
+{
+ if ( d->readOnly ) return;
+
+ d->autoScroll = false;
+
+ if ( ev->button() == LeftButton && d->targetTab != 0 )
+ {
+ emit tabMoved( d->activeTab-1, d->targetTab-1 );
+ d->targetTab = 0;
+ }
+}
+
+void KoTabBar::mouseMoveEvent( QMouseEvent* ev )
+{
+ if ( d->readOnly ) return;
+
+ QPoint pos = ev->pos();
+ if( !d->reverseLayout) pos = pos - QPoint( d->offset,0 );
+
+ // check if user drags a tab to move it
+ int i = d->tabAt( pos ) + 1;
+ if( ( i > 0 ) && ( i != d->targetTab ) )
+ {
+ if( i == d->activeTab ) i = 0;
+ if( i == d->activeTab+1 ) i = 0;
+
+ if( i != d->targetTab )
+ {
+ d->targetTab = i;
+ d->autoScroll = false;
+ update();
+ }
+ }
+
+ // drag past the very latest visible tab
+ // e.g move a tab to the last ordering position
+ QRect r = d->tabRects[ d->tabRects.count()-1 ];
+ bool moveToLast = false;
+ if( r.isValid() )
+ {
+ if( !d->reverseLayout )
+ if( pos.x() > r.right() )
+ if( pos.x() < width() )
+ moveToLast = true;
+ if( d->reverseLayout )
+ if( pos.x() < r.x() )
+ if( pos.x() > 0 )
+ moveToLast = true;
+ }
+ if( moveToLast )
+ if( d->targetTab != (int)d->tabRects.count()+1 )
+ {
+ d->targetTab = d->tabRects.count()+1;
+ d->autoScroll = false;
+ update();
+ }
+
+ // outside far too left ? activate autoscroll...
+ if ( pos.x() < 0 && !d->autoScroll )
+ {
+ d->autoScroll = true;
+ autoScrollBack();
+ }
+
+ // outside far too right ? activate autoscroll...
+ int w = width() - d->offset;
+ if ( pos.x() > w && !d->autoScroll )
+ {
+ d->autoScroll = true;
+ autoScrollForward();
+ }
+}
+
+void KoTabBar::mouseDoubleClickEvent( QMouseEvent* ev )
+{
+ int offset = d->reverseLayout ? 0 : d->offset;
+ if( ev->pos().x() > offset )
+ if( !d->readOnly )
+ emit doubleClicked();
+}
+
+void KoTabBar::wheelEvent( QWheelEvent * e )
+{
+ if ( d->tabs.count() == 0 )
+ {
+ erase();
+ return;
+ }
+
+ // Currently one wheel movement is a delta of 120.
+ // The 'unused' delta is stored for devices that allow
+ // a higher scrolling resolution.
+ // The delta required to move one tab is one wheel movement:
+ const int deltaRequired = 120;
+
+ d->wheelDelta += e->delta();
+ int tabDelta = - (d->wheelDelta / deltaRequired);
+ d->wheelDelta = d->wheelDelta % deltaRequired;
+ int numTabs = d->tabs.size();
+
+ if(d->activeTab + tabDelta > numTabs)
+ {
+ // Would take us past the last tab
+ d->activeTab = numTabs;
+ }
+ else if (d->activeTab + tabDelta < 1)
+ {
+ // Would take us before the first tab
+ d->activeTab = 1;
+ }
+ else
+ {
+ d->activeTab = d->activeTab + tabDelta;
+ }
+
+ // Find the left and right edge of the new tab. If we're
+ // going forward, and the right of the new tab isn't visible
+ // then scroll forward. Likewise, if going back, and the
+ // left of the new tab isn't visible, then scroll back.
+ int activeTabRight = d->tabRects[ d->activeTab-1 ].right();
+ int activeTabLeft = d->tabRects[ d->activeTab-1 ].left();
+ if(tabDelta > 0 && activeTabRight > width() - d->offset )
+ {
+ scrollForward();
+ }
+ else if(tabDelta < 0 && activeTabLeft < width() - d->offset )
+ {
+ scrollBack();
+ }
+
+ update();
+ emit tabChanged( d->tabs[ d->activeTab-1] );
+}
+
+
+#include "KoTabBar.moc"
diff --git a/lib/kofficeui/KoTabBar.h b/lib/kofficeui/KoTabBar.h
new file mode 100644
index 00000000..e582c3d2
--- /dev/null
+++ b/lib/kofficeui/KoTabBar.h
@@ -0,0 +1,275 @@
+/* This file is part of the KDE project
+ Copyright (C) 2003 Ariya Hidayat <ariya@kde.org>
+ Copyright (C) 2003 Norbert Andres <nandres@web.de>
+ Copyright (C) 2002 Laurent Montel <montel@kde.org>
+ Copyright (C) 1999 David Faure <faure@kde.org>
+ Copyright (C) 1999 Boris Wedl <boris.wedl@kfunigraz.ac.at>
+ Copyright (C) 1998-2000 Torben Weis <weis@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#ifndef kotabbar_h
+#define kotabbar_h
+
+#include <qwidget.h>
+#include <qstringlist.h>
+#include <koffice_export.h>
+class KoTabBarPrivate;
+
+/**
+ * The KoTabBar class provides a tab bar, for use to switch active
+ * page/sheet in a document.
+ *
+ * The tab bar is typically used in the main view.
+ * It is the small widget on the bottom left corner.
+ * Pages/sheets are displayed as tabs, clicking on
+ * one of the tab will activate the corresponding sheet (this is actually
+ * done in main view). Current active page/sheet is marked by bold text.
+ *
+ * The tab bar supports page/sheet reorder by dragging a certain tab
+ * and move it to another location. The main view should handle the necessary
+ * action to perform the actual reorder.
+ *
+ * There are four scroll buttons available in the tab bar. They are used
+ * to shift the tabs in left and right direction, for example when there
+ * are more tabs than the space available to display all tabs.
+ *
+ * Since a page/sheet can be hidden, the tab bar only shows the visible page/sheet.
+ * When a hidden page or sheet is shown again, it will be on the same position as
+ * before it was hidden.
+ *
+ * When the document is protected, it is necessary to set the tab bar as
+ * read-only using setReadOnly (see also readOnly). If it is set to true,
+ * tabs can not be moved by dragging and context menu will not be displayed.
+ *
+ * @short A bar with tabs and scroll buttons.
+ */
+class KOFFICEUI_EXPORT KoTabBar : public QWidget
+{
+ Q_OBJECT
+
+ Q_PROPERTY( QString activeTab READ activeTab WRITE setActiveTab )
+ Q_PROPERTY( bool readOnly READ readOnly WRITE setReadOnly )
+ Q_PROPERTY( QStringList tabs READ tabs WRITE setTabs )
+ Q_PROPERTY( unsigned count READ count )
+
+public:
+
+ /**
+ * Creates a new tabbar.
+ */
+ KoTabBar( QWidget* parent = 0, const char *name = 0 );
+
+ /**
+ * Destroy the tabbar.
+ */
+ virtual ~KoTabBar();
+
+ /**
+ * Returns true if the tab bar is read only.
+ */
+ bool readOnly() const;
+
+ /**
+ * Returns true if tabs and scroll buttons will be laid out in a mirrored
+ * (right to left) fashion.
+ */
+ bool reverseLayout() const;
+
+ /**
+ * Returns all the tab as list of strings.
+ */
+ QStringList tabs() const;
+
+ /**
+ * Returns number of tabs.
+ * This is the same as KoTabBar::tabs().count()
+ */
+ unsigned count() const;
+
+ /**
+ * Returns the active tab.
+ */
+ QString activeTab() const;
+
+ /**
+ * Returns true if it is possible to scroll one tab back.
+ *
+ * \sa scrollBack
+ */
+ bool canScrollBack() const;
+
+ /**
+ * Returns true if it is possible to scroll one tab forward.
+ *
+ * \sa scrollForward
+ */
+ bool canScrollForward() const;
+
+ /**
+ * Ensures that specified tab is visible.
+ */
+ void ensureVisible( const QString& tab );
+
+public slots:
+
+ /**
+ * Replaces all tabs with the list of strings.
+ */
+ void setTabs( const QStringList& list );
+
+ /**
+ * Sets the tab bar to be read only.
+ *
+ * If the tab bar is read only, tab reordering is not allowed.
+ * This means that signal tabMoved, contextMenu and doubleClicked
+ * would not be emitted.
+ */
+ void setReadOnly( bool ro );
+
+ /**
+ * If reverse is true, dialogs and scroll buttonswidgets will be laid out in a mirrored
+ * as if the sheet is in right to left languages (such as Arabic and Hebrew)
+ */
+ void setReverseLayout( bool reverse );
+
+ /**
+ * Adds a tab to the tab bar.
+ */
+ void addTab( const QString& text );
+
+ /**
+ * Removes a tab from the bar. If the tab was the active one then
+ * no tab will be active.
+ * It is recommended to call setActiveTab after a call to this function.
+ */
+ void removeTab( const QString& text );
+
+ /**
+ * Renames a tab.
+ */
+ void renameTab( const QString& old_name, const QString& new_name );
+
+ /**
+ * Moves a tab to another position and reorder other tabs.
+ *
+ * Example 1: if there are four tabs A - B - C - D, then
+ * moveTab(2,1) will yield A - C - B - D. This is because
+ * 2nd tab (i.e C) is moved to a position before 1th tab (i.e B).
+ *
+ * Example 2: for these tabs: X - Y - Z, moveTab(0,3) will
+ * move tab X after tab Z so that the result is Y - Z - X.
+ */
+ void moveTab( unsigned tab, unsigned target );
+
+ /**
+ * Scrolls one tab back. Does nothing if the leftmost tab (rightmost tab
+ * when reverseLayout is true) is already the first tab.
+ *
+ * \sa canScrollBack
+ */
+ void scrollBack();
+
+ /**
+ * Scrolls one tab forward. Does nothing if the rightmost tab (leftmost tab
+ * when reverseLayout is true) is already the last tab.
+ *
+ * \sa canScrollForward
+ */
+ void scrollForward();
+
+ /**
+ * Scrolls to the first tab. Does nothing if the leftmost tab (rightmost tab
+ * when reverseLayout is true) is already the first tab.
+ *
+ * \sa canScrollBack
+ */
+ void scrollFirst();
+
+ /**
+ * Scrolls to the last tab. Does nothing if the rightmost tab (leftmost tab
+ * when reverseLayout is true) is already the last tab.
+ *
+ * \sa canScrollForward
+ */
+ void scrollLast();
+
+ /**
+ * Sets active tab.
+ */
+ void setActiveTab( const QString& text );
+
+ /**
+ * Removes all tabs.
+ */
+ void clear();
+
+ QSize sizeHint() const;
+
+signals:
+
+ /**
+ * Emitted if the active tab changed.
+ */
+ void tabChanged( const QString& _text );
+
+ /**
+ * This signal is emitted whenever a tab is dragged, moved and
+ * released. This means that the user wants to move a tab into
+ * another position (right before target).
+ *
+ * When the signal is emitted, the tabs are not reordered.
+ * Therefore if you just ignore this signal, than no tab reorder
+ * is possible. Call moveTab (from the slot connected to this signal)
+ * to perform the actual tab reorder.
+ */
+ void tabMoved( unsigned tab, unsigned target );
+
+ /**
+ * This signal is emitted whenever the tab bar is right-clicked.
+ * Typically it is used to popup a context menu.
+ */
+ void contextMenu( const QPoint& pos );
+
+ /**
+ * This signal is emitted whenever the tab bar is double-clicked.
+ */
+ void doubleClicked();
+
+protected slots:
+ void autoScrollBack();
+ void autoScrollForward();
+
+protected:
+ virtual void paintEvent ( QPaintEvent* ev );
+ virtual void resizeEvent( QResizeEvent* ev );
+ virtual void mousePressEvent ( QMouseEvent* ev );
+ virtual void mouseReleaseEvent ( QMouseEvent* ev );
+ virtual void mouseDoubleClickEvent ( QMouseEvent* ev );
+ virtual void mouseMoveEvent ( QMouseEvent* ev );
+ virtual void wheelEvent ( QWheelEvent * e );
+
+private:
+ KoTabBarPrivate *d;
+
+ // don't allow copy or assignment
+ KoTabBar( const KoTabBar& );
+ KoTabBar& operator=( const KoTabBar& );
+};
+
+
+#endif // kotabbar_h
diff --git a/lib/kofficeui/KoTabChooser.cpp b/lib/kofficeui/KoTabChooser.cpp
new file mode 100644
index 00000000..414db6bb
--- /dev/null
+++ b/lib/kofficeui/KoTabChooser.cpp
@@ -0,0 +1,175 @@
+/* This file is part of the KDE project
+ Copyright (C) 1998, 1999 Reginald Stadlbauer <reggie@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+// Description: Tabulator chooser (header)
+
+/******************************************************************/
+
+#include <KoTabChooser.h>
+#include <qpainter.h>
+#include <qpopupmenu.h>
+#include <qcursor.h>
+
+#include <klocale.h>
+
+
+class KoTabChooserPrivate {
+public:
+ KoTabChooserPrivate() {
+ }
+ ~KoTabChooserPrivate() {}
+
+ bool m_bReadWrite;
+};
+
+/******************************************************************/
+/* Class: KoTabChooser */
+/******************************************************************/
+
+/*================================================================*/
+KoTabChooser::KoTabChooser( QWidget *parent, int _flags )
+ : QFrame( parent, "" )
+{
+ setFrameStyle( MenuBarPanel );
+ flags = _flags;
+ d=new KoTabChooserPrivate();
+
+ d->m_bReadWrite=true;
+
+ currType = 0;
+
+ if ( flags & TAB_DEC_PNT ) currType = TAB_DEC_PNT;
+ if ( flags & TAB_CENTER ) currType = TAB_CENTER;
+ if ( flags & TAB_RIGHT ) currType = TAB_RIGHT;
+ if ( flags & TAB_LEFT ) currType = TAB_LEFT;
+
+ setupMenu();
+}
+
+/*================================================================*/
+void KoTabChooser::mousePressEvent( QMouseEvent *e )
+{
+ if ( currType == 0 ) return;
+
+ if( !d->m_bReadWrite)
+ return;
+
+ switch ( e->button() ) {
+ case LeftButton: case MidButton: {
+ switch ( currType ) {
+ case TAB_LEFT: {
+ if ( flags & TAB_CENTER ) currType = TAB_CENTER;
+ else if ( flags & TAB_RIGHT ) currType = TAB_RIGHT;
+ else if ( flags & TAB_DEC_PNT ) currType = TAB_DEC_PNT;
+ } break;
+ case TAB_RIGHT: {
+ if ( flags & TAB_DEC_PNT ) currType = TAB_DEC_PNT;
+ else if ( flags & TAB_LEFT ) currType = TAB_LEFT;
+ else if ( flags & TAB_CENTER ) currType = TAB_CENTER;
+ } break;
+ case TAB_CENTER: {
+ if ( flags & TAB_RIGHT ) currType = TAB_RIGHT;
+ else if ( flags & TAB_DEC_PNT ) currType = TAB_DEC_PNT;
+ else if ( flags & TAB_LEFT ) currType = TAB_LEFT;
+ } break;
+ case TAB_DEC_PNT: {
+ if ( flags & TAB_LEFT ) currType = TAB_LEFT;
+ else if ( flags & TAB_CENTER ) currType = TAB_CENTER;
+ else if ( flags & TAB_RIGHT ) currType = TAB_RIGHT;
+ } break;
+ }
+ repaint( true );
+ } break;
+ case RightButton: {
+ QPoint pnt( QCursor::pos() );
+
+ rb_menu->setItemChecked( mLeft, false );
+ rb_menu->setItemChecked( mCenter, false );
+ rb_menu->setItemChecked( mRight, false );
+ rb_menu->setItemChecked( mDecPoint, false );
+
+ switch ( currType ) {
+ case TAB_LEFT: rb_menu->setItemChecked( mLeft, true );
+ break;
+ case TAB_CENTER: rb_menu->setItemChecked( mCenter, true );
+ break;
+ case TAB_RIGHT: rb_menu->setItemChecked( mRight, true );
+ break;
+ case TAB_DEC_PNT: rb_menu->setItemChecked( mDecPoint, true );
+ break;
+ }
+
+ rb_menu->popup( pnt );
+ } break;
+ default: break;
+ }
+}
+
+/*================================================================*/
+void KoTabChooser::drawContents( QPainter *painter )
+{
+ if ( currType == 0 ) return;
+
+ painter->setPen( QPen( black, 2, SolidLine ) );
+
+ switch ( currType ) {
+ case TAB_LEFT: {
+ painter->drawLine( 4, height() - 4, width() - 4, height() - 4 );
+ painter->drawLine( 5, 4, 5, height() - 4 );
+ } break;
+ case TAB_CENTER: {
+ painter->drawLine( 4, height() - 4, width() - 4, height() - 4 );
+ painter->drawLine( width() / 2, 4, width() / 2, height() - 4 );
+ } break;
+ case TAB_RIGHT: {
+ painter->drawLine( 4, height() - 4, width() - 4, height() - 4 );
+ painter->drawLine( width() - 5, 4, width() - 5, height() - 4 );
+ } break;
+ case TAB_DEC_PNT: {
+ painter->drawLine( 4, height() - 4, width() - 4, height() - 4 );
+ painter->drawLine( width() / 2, 4, width() / 2, height() - 4 );
+ painter->fillRect( width() / 2 + 2, height() - 9, 3, 3, black );
+ } break;
+ default: break;
+ }
+}
+
+/*================================================================*/
+void KoTabChooser::setupMenu()
+{
+ rb_menu = new QPopupMenu();
+ Q_CHECK_PTR( rb_menu );
+ mLeft = rb_menu->insertItem( i18n( "Tabulator &Left" ), this, SLOT( rbLeft() ) );
+ mCenter = rb_menu->insertItem( i18n( "Tabulator &Center" ), this, SLOT( rbCenter() ) );
+ mRight = rb_menu->insertItem( i18n( "Tabulator &Right" ), this, SLOT( rbRight() ) );
+ mDecPoint = rb_menu->insertItem( i18n( "Tabulator &Decimal Point" ), this, SLOT( rbDecPoint() ) );
+ rb_menu->setCheckable( false );
+}
+
+KoTabChooser::~KoTabChooser() {
+ delete rb_menu;
+ delete d;
+}
+
+void KoTabChooser::setReadWrite(bool _readWrite)
+{
+ d->m_bReadWrite=_readWrite;
+}
+
+#include <KoTabChooser.moc>
diff --git a/lib/kofficeui/KoTabChooser.h b/lib/kofficeui/KoTabChooser.h
new file mode 100644
index 00000000..7a49f495
--- /dev/null
+++ b/lib/kofficeui/KoTabChooser.h
@@ -0,0 +1,80 @@
+/* This file is part of the KDE project
+ Copyright (C) 1998, 1999 Reginald Stadlbauer <reggie@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#ifndef koTabChooser_h
+#define koTabChooser_h
+
+#include <qframe.h>
+#include <koffice_export.h>
+class QMouseEvent;
+class QPainter;
+class QPopupMenu;
+
+/**
+ * class KoTabChooser
+ */
+
+class KoTabChooserPrivate;
+
+class KOFFICEUI_EXPORT KoTabChooser : public QFrame
+{
+ Q_OBJECT
+
+public:
+ enum { TAB_LEFT = 1,
+ TAB_CENTER = 2,
+ TAB_RIGHT = 4,
+ TAB_DEC_PNT = 8,
+ TAB_ALL = TAB_LEFT | TAB_CENTER | TAB_RIGHT | TAB_DEC_PNT };
+
+ KoTabChooser( QWidget *parent, int _flags );
+ ~KoTabChooser();
+
+ int getCurrTabType() { return currType; }
+
+ /**
+ * put m_bReadWrite to true as default
+ * and used setReadWrite(false) to make in readOnly mode
+ */
+ void setReadWrite(bool _readWrite);
+
+protected:
+ void mousePressEvent( QMouseEvent *e );
+ void drawContents( QPainter *painter );
+ void setupMenu();
+
+ int flags;
+ int currType;
+ QPopupMenu *rb_menu;
+ int mLeft;
+ int mRight;
+ int mCenter;
+ int mDecPoint;
+
+ KoTabChooserPrivate *d;
+
+protected slots:
+ void rbLeft() { currType = TAB_LEFT; repaint( true ); }
+ void rbCenter() { currType = TAB_CENTER; repaint( true ); }
+ void rbRight() { currType = TAB_RIGHT; repaint( true ); }
+ void rbDecPoint() { currType = TAB_DEC_PNT; repaint( true ); }
+
+};
+
+#endif
diff --git a/lib/kofficeui/KoTemplateChooseDia.cpp b/lib/kofficeui/KoTemplateChooseDia.cpp
new file mode 100644
index 00000000..1c2fd843
--- /dev/null
+++ b/lib/kofficeui/KoTemplateChooseDia.cpp
@@ -0,0 +1,829 @@
+/* This file is part of the KDE project
+ Copyright (C) 1998, 1999 Reginald Stadlbauer <reggie@kde.org>
+ 2000, 2001 Werner Trobin <trobin@kde.org>
+ 2002, 2003 Thomas Nagy <tnagy@eleve.emn.fr>
+ 2004 David Faure <faure@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// Description: Template Choose Dialog
+
+/******************************************************************/
+
+#include "KoTemplateChooseDia.h"
+
+#include <klocale.h>
+#include <kdeversion.h>
+#include <kfiledialog.h>
+#include <kinstance.h>
+#include <KoFilterManager.h>
+#include <KoTemplates.h>
+#include <KoDocument.h>
+#include <kmainwindow.h>
+
+#include <kdebug.h>
+#include <kpushbutton.h>
+#include <kjanuswidget.h>
+#include <kglobalsettings.h>
+#include <ktextedit.h>
+#include <kfileiconview.h>
+#include <kfileitem.h>
+#include <kmessagebox.h>
+#include <kapplication.h>
+#include <kaboutdata.h>
+
+#include <qapplication.h>
+#include <qlayout.h>
+#include <qtabwidget.h>
+#include <qcombobox.h>
+#include <qcheckbox.h>
+#include <qpoint.h>
+#include <qobjectlist.h>
+#include <qvgroupbox.h>
+#include <qtooltip.h>
+
+class MyFileDialog : public KFileDialog
+{
+ public :
+ MyFileDialog(
+ const QString& startDir=0,
+ const QString& filter =0,
+ QWidget *parent=0,
+ const char *name=0,
+ bool modal=0)
+ : KFileDialog (startDir, filter, parent, name, modal),
+ m_slotOkCalled( false ) {}
+
+ KURL currentURL()
+ {
+ setResult( QDialog::Accepted ); // selectedURL tests for it
+ return KFileDialog::selectedURL();
+ }
+
+ // Return true if the current URL exists, show msg box if not
+ bool checkURL()
+ {
+ bool ok = true;
+ KURL url = currentURL();
+ if ( url.isLocalFile() )
+ {
+ ok = QFile::exists( url.path() );
+ if ( !ok ) {
+ // Maybe offer to create a new document with that name? (see alos KoDocument::openFile)
+ KMessageBox::error( this, i18n( "The file %1 does not exist." ).arg( url.path() ) );
+ }
+ }
+ return ok;
+ }
+ // Called directly by pressing Return in the location combo
+ // (so we need to remember that it got called, to avoid calling it twice)
+ // Called "by hand" when clicking on our OK button
+ void slotOk() {
+ m_slotOkCalled = true;
+ KFileDialog::slotOk();
+ }
+ bool slotOkCalled() const { return m_slotOkCalled; }
+ protected:
+ // Typing a file that doesn't exist closes the file dialog, we have to
+ // handle this case better here.
+ virtual void accept() {
+ if ( checkURL() )
+ KFileDialog::accept();
+ }
+
+ virtual void reject() {
+ KFileDialog::reject();
+ emit cancelClicked();
+ }
+private:
+ bool m_slotOkCalled;
+};
+
+/*================================================================*/
+
+/*================================================================*/
+
+class KoTemplateChooseDiaPrivate {
+ public:
+ KoTemplateChooseDiaPrivate(const QCString& templateType, KInstance* instance,
+ const QCString &format,
+ const QString &nativeName,
+ const QStringList& extraNativeMimeTypes,
+ const KoTemplateChooseDia::DialogType &dialogType) :
+ m_templateType(templateType), m_instance(instance), m_format(format),
+ m_nativeName(nativeName), m_extraNativeMimeTypes( extraNativeMimeTypes ),
+ m_dialogType(dialogType), tree(0),
+ m_nostartupdlg( false ),
+ m_mainwidget(0), m_nodiag( 0 )
+ {
+ m_returnType = KoTemplateChooseDia::Empty;
+ }
+
+ ~KoTemplateChooseDiaPrivate() {}
+
+ QCString m_templateType;
+ KInstance* m_instance;
+ QCString m_format;
+ QString m_nativeName;
+ QStringList m_extraNativeMimeTypes;
+
+ KoTemplateChooseDia::DialogType m_dialogType;
+ KoTemplateTree *tree;
+
+ QString m_templateName;
+ QString m_fullTemplateName;
+ KoTemplateChooseDia::ReturnType m_returnType;
+
+ bool m_nostartupdlg;
+
+ // the main widget
+ QWidget *m_mainwidget;
+
+ // do not show this dialog at startup
+ QCheckBox *m_nodiag;
+
+ // choose a template
+ KJanusWidget * m_jwidget;
+ KFileIconView *m_recent;
+ QVGroupBox * boxdescription;
+ KTextEdit * textedit;
+
+ // choose a file
+ MyFileDialog *m_filedialog;
+
+ // for the layout
+ QTabWidget* tabWidget;
+ QWidget* newTab;
+ QWidget* existingTab;
+ QWidget* recentTab;
+
+};
+
+/******************************************************************/
+/* Class: KoTemplateChooseDia */
+/******************************************************************/
+
+/*================================================================*/
+KoTemplateChooseDia::KoTemplateChooseDia(QWidget *parent, const char *name, KInstance* instance,
+ const QCString &format,
+ const QString &nativeName,
+ const QStringList &extraNativeMimeTypes,
+ const DialogType &dialogType,
+ const QCString& templateType) :
+ KDialogBase(parent, name, true, i18n("Open Document"), KDialogBase::Ok | KDialogBase::Cancel,
+ KDialogBase::Ok)
+{
+ d = new KoTemplateChooseDiaPrivate(
+ templateType,
+ instance,
+ format,
+ nativeName,
+ extraNativeMimeTypes,
+ dialogType);
+
+ QPushButton* ok = actionButton( KDialogBase::Ok );
+ QPushButton* cancel = actionButton( KDialogBase::Cancel );
+ cancel->setAutoDefault(false);
+ ok->setDefault(true);
+ //enableButtonOK(false);
+
+ if (!templateType.isNull() && !templateType.isEmpty() && dialogType!=NoTemplates)
+ d->tree = new KoTemplateTree(templateType, instance, true);
+
+ d->m_mainwidget = makeMainWidget();
+
+ d->m_templateName = "";
+ d->m_fullTemplateName = "";
+ d->m_returnType = Cancel;
+
+ setupDialog();
+}
+
+KoTemplateChooseDia::~KoTemplateChooseDia()
+{
+ delete d->tree;
+ delete d;
+ d=0L;
+}
+
+// Keep in sync with KoMainWindow::chooseNewDocument
+static bool cancelQuits() {
+ bool onlyDoc = !KoDocument::documentList() || KoDocument::documentList()->count() <= 1;
+ bool onlyMainWindow = !KMainWindow::memberList || KMainWindow::memberList->count() <= 1;
+ return onlyDoc && onlyMainWindow && kapp->instanceName() != "koshell"; // hack for koshell
+}
+
+KoTemplateChooseDia::ReturnType KoTemplateChooseDia::choose(KInstance* instance, QString &file,
+ const KoTemplateChooseDia::DialogType &dialogType,
+ const QCString& templateType,
+ QWidget* parent)
+{
+ const QString nativeName = instance->aboutData()->programName();
+ const QCString format = KoDocument::readNativeFormatMimeType( instance );
+ const QStringList extraNativeMimeTypes = KoDocument::readExtraNativeMimeTypes( instance );
+ // Maybe the above two can be combined into one call, for speed:
+ //KoDocument::getNativeMimeTypeInfo( instance, nativeName, extraNativeMimeTypes );
+ return choose( instance, file, format, nativeName, extraNativeMimeTypes,
+ dialogType, templateType, parent );
+}
+
+KoTemplateChooseDia::ReturnType KoTemplateChooseDia::choose(KInstance* instance, QString &file,
+ const QCString &format,
+ const QString &nativeName,
+ const QStringList& extraNativeMimeTypes,
+ const DialogType &dialogType,
+ const QCString& templateType,
+ QWidget* parent )
+{
+ KoTemplateChooseDia *dlg = new KoTemplateChooseDia(
+ parent, "Choose", instance, format,
+ nativeName, extraNativeMimeTypes, dialogType, templateType );
+
+ KoTemplateChooseDia::ReturnType rt = Cancel;
+
+ if (dlg->noStartupDlg())
+ {
+ // start with the default template
+ file = dlg->getFullTemplate();
+ rt = dlg->getReturnType();
+ }
+ else
+ {
+ dlg->resize( 700, 480 );
+ if ( dlg->exec() == QDialog::Accepted )
+ {
+ file = dlg->getFullTemplate();
+ rt = dlg->getReturnType();
+ }
+ }
+
+ delete dlg;
+ return rt;
+}
+
+bool KoTemplateChooseDia::noStartupDlg() const {
+ return d->m_nostartupdlg;
+}
+
+
+QString KoTemplateChooseDia::getTemplate() const{
+ return d->m_templateName;
+}
+
+QString KoTemplateChooseDia::getFullTemplate() const{
+ return d->m_fullTemplateName;
+}
+
+KoTemplateChooseDia::ReturnType KoTemplateChooseDia::getReturnType() const {
+ return d->m_returnType;
+}
+
+KoTemplateChooseDia::DialogType KoTemplateChooseDia::getDialogType() const {
+ return d->m_dialogType;
+}
+
+/*================================================================*/
+// private
+void KoTemplateChooseDia::setupRecentDialog(QWidget * widgetbase, QGridLayout * layout)
+{
+
+ d->m_recent = new KoTCDRecentFilesIconView(widgetbase, "recent files");
+ // I prefer the icons to be in "most recent first" order (DF)
+ d->m_recent->setSorting( static_cast<QDir::SortSpec>( QDir::Time | QDir::Reversed ) );
+ layout->addWidget(d->m_recent,0,0);
+
+ QString oldGroup = d->m_instance->config()->group();
+ d->m_instance->config()->setGroup( "RecentFiles" );
+
+ int i = 0;
+ QString value;
+ do {
+ QString key=QString( "File%1" ).arg( i );
+ value=d->m_instance->config()->readPathEntry( key );
+ if ( !value.isEmpty() ) {
+ // Support for kdelibs-3.5's new RecentFiles format: name[url]
+ QString s = value;
+ if ( s.endsWith("]") )
+ {
+ int pos = s.find("[");
+ s = s.mid( pos + 1, s.length() - pos - 2);
+ }
+ KURL url(s);
+
+ if(!url.isLocalFile() || QFile::exists(url.path())) {
+ KFileItem *item = new KFileItem( KFileItem::Unknown, KFileItem::Unknown, url );
+ d->m_recent->insertItem(item);
+ }
+ }
+ i++;
+ } while ( !value.isEmpty() || i<=10 );
+
+ d->m_instance->config()->setGroup( oldGroup );
+ d->m_recent->showPreviews();
+
+ connect(d->m_recent, SIGNAL( doubleClicked ( QIconViewItem * ) ),
+ this, SLOT( recentSelected( QIconViewItem * ) ) );
+
+}
+
+/*================================================================*/
+// private
+void KoTemplateChooseDia::setupFileDialog(QWidget * widgetbase, QGridLayout * layout)
+{
+ QString dir = QString::null;
+ QPoint point( 0, 0 );
+
+ d->m_filedialog=new MyFileDialog(dir,
+ QString::null,
+ widgetbase,
+ "file dialog",
+ false);
+
+ layout->addWidget(d->m_filedialog,0,0);
+ d->m_filedialog->reparent( widgetbase , point );
+ //d->m_filedialog->setOperationMode( KFileDialog::Opening);
+
+ QObjectList *l = d->m_filedialog->queryList( "QPushButton" );
+ QObjectListIt childit( *l );
+ QObject *obj;
+ while ( (obj = childit.current()) != 0 ) {
+ ++childit;
+ ((QPushButton*)obj)->hide();
+ }
+ delete l;
+
+ d->m_filedialog->setSizeGripEnabled ( FALSE );
+
+ QStringList mimeFilter = KoFilterManager::mimeFilter( d->m_format, KoFilterManager::Import );
+ QStringList::Iterator mimeFilterIt = mimeFilter.at( 1 );
+ for ( QStringList::ConstIterator it = d->m_extraNativeMimeTypes.begin();
+ it != d->m_extraNativeMimeTypes.end(); ++it ) {
+ mimeFilterIt = mimeFilter.insert( mimeFilterIt, *it );
+ ++mimeFilterIt;
+ }
+ d->m_filedialog->setMimeFilter( mimeFilter );
+
+ connect(d->m_filedialog, SIGNAL( okClicked() ),
+ this, SLOT ( slotOk() ));
+
+ connect(d->m_filedialog, SIGNAL( cancelClicked() ),
+ this, SLOT ( slotCancel() ));
+
+}
+
+/*================================================================*/
+// private
+void KoTemplateChooseDia::setupTemplateDialog(QWidget * widgetbase, QGridLayout * layout)
+{
+
+ d->m_jwidget = new KJanusWidget(
+ widgetbase,
+ "kjanuswidget",
+ KJanusWidget::IconList);
+ layout->addWidget(d->m_jwidget,0,0);
+
+ d->boxdescription = new QVGroupBox(
+ i18n("Selected Template"),
+ widgetbase,
+ "boxdescription");
+ layout->addWidget(d->boxdescription, 1, 0 );
+
+ // config
+ KConfigGroup grp( d->m_instance->config(), "TemplateChooserDialog" );
+ int templateNum = grp.readNumEntry( "TemplateTab", -1 );
+ QString templateName = grp.readPathEntry( "TemplateName" );
+ if ( templateName.isEmpty() && d->tree->defaultTemplate() )
+ templateName = d->tree->defaultTemplate()->name(); //select the default template for the app
+
+ // item which will be selected initially
+ QIconViewItem * itemtoselect = 0;
+
+ // count the templates inserted
+ int entriesnumber = 0;
+ int defaultTemplateGroup = -1;
+
+ for ( KoTemplateGroup *group = d->tree->first(); group!=0L; group=d->tree->next() )
+ {
+ if (group->isHidden())
+ continue;
+
+ if ( d->tree->defaultGroup() == group )
+ defaultTemplateGroup = entriesnumber; //select the default template group for the app
+
+ QFrame * frame = d->m_jwidget->addPage (
+ group->name(),
+ group->name(),
+ group->first()->loadPicture(d->m_instance));
+
+ QGridLayout * layout = new QGridLayout(frame);
+ KoTCDIconCanvas *canvas = new KoTCDIconCanvas( frame );
+ layout->addWidget(canvas,0,0);
+
+ canvas->setBackgroundColor( colorGroup().base() );
+ canvas->setResizeMode(QIconView::Adjust);
+ canvas->setWordWrapIconText( true );
+ canvas->show();
+
+ QIconViewItem * tempitem = canvas->load(group, templateName, d->m_instance);
+ if (tempitem)
+ itemtoselect = tempitem;
+
+ canvas->sort();
+ canvas->setSelectionMode(QIconView::Single);
+
+ connect( canvas, SIGNAL( clicked ( QIconViewItem * ) ),
+ this, SLOT( currentChanged( QIconViewItem * ) ) );
+
+ connect( canvas, SIGNAL( doubleClicked( QIconViewItem * ) ),
+ this, SLOT( chosen(QIconViewItem *) ) );
+
+ entriesnumber++;
+ }
+
+ d->boxdescription->setInsideMargin ( 3 );
+ d->boxdescription->setInsideSpacing ( 3 );
+
+ d->textedit = new KTextEdit( d->boxdescription );
+ d->textedit->setReadOnly(1);
+ d->textedit->setText(descriptionText(i18n("Empty Document"), i18n("Creates an empty document")));
+ d->textedit->setLineWidth(0);
+ d->textedit->setMaximumHeight(50);
+
+ // Hide the widget if there is no template available. This should never happen ;-)
+ if (!entriesnumber)
+ d->m_jwidget->hide();
+
+ // Set the initially shown page, possibly from the last usage of the dialog
+ if (entriesnumber >= templateNum && templateNum != -1 )
+ d->m_jwidget->showPage(templateNum);
+ else if ( defaultTemplateGroup != -1)
+ d->m_jwidget->showPage(defaultTemplateGroup);
+
+
+ // Set the initially selected template, possibly from the last usage of the dialog
+ currentChanged(itemtoselect);
+
+ // setup the checkbox
+ QString translatedstring = i18n("Always start %1 with the selected template").arg(d->m_nativeName);
+
+ d->m_nodiag = new QCheckBox ( translatedstring , widgetbase);
+ layout->addWidget(d->m_nodiag, 2, 0);
+ QString startwithoutdialog = grp.readEntry( "NoStartDlg" );
+ bool ischecked = startwithoutdialog == QString("yes");
+
+ // When not starting up, display a tri-state button telling whether
+ // the user actually choosed the template to start with next times (bug:77542)
+ if (d->m_dialogType == Everything)
+ {
+ d->m_nodiag->setChecked( ischecked );
+ }
+ else
+ {
+ d->m_nodiag->setTristate();
+ d->m_nodiag->setNoChange();
+ }
+}
+
+/*================================================================*/
+// private
+void KoTemplateChooseDia::setupDialog()
+{
+
+ QGridLayout *maingrid=new QGridLayout( d->m_mainwidget, 1, 1, 2, 6);
+ KConfigGroup grp( d->m_instance->config(), "TemplateChooserDialog" );
+
+ if (d->m_dialogType == Everything)
+ {
+
+ // the user may want to start with his favorite template
+ if (grp.readEntry( "NoStartDlg" ) == QString("yes") )
+ {
+ d->m_nostartupdlg = true;
+ d->m_returnType = Empty;
+
+ // no default template, just start with an empty document
+ if (grp.readEntry("LastReturnType") == QString("Empty") )
+ return;
+
+ // start with the default template
+ d->m_templateName = grp.readPathEntry( "TemplateName" );
+ d->m_fullTemplateName = grp.readPathEntry( "FullTemplateName" );
+
+ // be paranoid : invalid template means empty template
+ if (!QFile::exists(d->m_fullTemplateName))
+ return;
+
+ if (d->m_fullTemplateName.length() < 2)
+ return;
+
+ d->m_returnType = Template;
+ return;
+ }
+
+ if ( cancelQuits() )
+ setButtonCancel( KStdGuiItem::quit() );
+
+ d->tabWidget = new QTabWidget( d->m_mainwidget, "tabWidget" );
+ maingrid->addWidget( d->tabWidget, 0, 0 );
+
+ // new document
+ d->newTab = new QWidget( d->tabWidget, "newTab" );
+ d->tabWidget->insertTab( d->newTab, i18n( "&Create Document" ) );
+ QGridLayout * newTabLayout = new QGridLayout( d->newTab, 1, 1, KDialogBase::marginHint(), KDialogBase::spacingHint());
+
+ // existing document
+ d->existingTab = new QWidget( d->tabWidget, "existingTab" );
+ d->tabWidget->insertTab( d->existingTab, i18n( "Open &Existing Document" ) );
+ QGridLayout * existingTabLayout = new QGridLayout( d->existingTab, 1, 1, 0, KDialog::spacingHint());
+
+ // recent document
+ d->recentTab = new QWidget( d->tabWidget, "recentTab" );
+ d->tabWidget->insertTab( d->recentTab, i18n( "Open &Recent Document" ) );
+ QGridLayout * recentTabLayout = new QGridLayout( d->recentTab, 1, 1, KDialogBase::marginHint(), KDialog::spacingHint());
+
+ setupTemplateDialog(d->newTab, newTabLayout);
+ setupFileDialog(d->existingTab, existingTabLayout);
+ setupRecentDialog(d->recentTab, recentTabLayout);
+
+ QString tabhighlighted = grp.readEntry("LastReturnType");
+ if ( tabhighlighted == "Template" )
+ d->tabWidget->setCurrentPage(0); // CreateDocument tab
+ else if (tabhighlighted == "File" )
+ d->tabWidget->setCurrentPage(2); // RecentDocument tab
+ else
+ d->tabWidget->setCurrentPage(0); // Default setting: CreateDocument tab
+ }
+ else
+ {
+
+ // open a file
+ if (d->m_dialogType == NoTemplates)
+ {
+ setupFileDialog(d->m_mainwidget, maingrid);
+ }
+ // create a new document from a template
+ if (d->m_dialogType == OnlyTemplates)
+ {
+ setCaption(i18n( "Create Document" ));
+ setupTemplateDialog(d->m_mainwidget, maingrid);
+ }
+ }
+}
+
+/*================================================================*/
+// private SLOT
+void KoTemplateChooseDia::currentChanged( QIconViewItem * item)
+{
+ if (item)
+ {
+ QIconView* canvas = item->iconView();
+
+ // set text in the textarea
+ d->textedit->setText( descriptionText(
+ item->text(),
+ ((KoTCDIconViewItem *) item)->getDescr()
+ ));
+
+ // set the icon in the canvas selected
+ if (canvas)
+ canvas->setSelected(item,1,0);
+
+ // register the current template
+ d->m_templateName = item->text();
+ d->m_fullTemplateName = ((KoTCDIconViewItem *) item)->getFName();
+ }
+}
+
+/*================================================================*/
+// private SLOT
+void KoTemplateChooseDia::chosen(QIconViewItem * item)
+{
+ // the user double clicked on a template
+ if (item)
+ {
+ currentChanged(item);
+ slotOk();
+ }
+}
+
+/* */
+// private SLOT
+void KoTemplateChooseDia::recentSelected( QIconViewItem * item)
+{
+ if (item)
+ {
+ slotOk();
+ }
+}
+
+/*================================================================*/
+// protected SLOT
+void KoTemplateChooseDia::slotOk()
+{
+ // Collect info from the dialog into d->m_returnType and d->m_templateName etc.
+ if (collectInfo())
+ {
+ // Save it for the next time
+ KConfigGroup grp( d->m_instance->config(), "TemplateChooserDialog" );
+ static const char* const s_returnTypes[] = { 0 /*Cancel ;)*/, "Template", "File", "Empty" };
+ if ( d->m_returnType <= Empty )
+ {
+ grp.writeEntry( "LastReturnType", QString::fromLatin1(s_returnTypes[d->m_returnType]) );
+ if (d->m_returnType == Template)
+ {
+ grp.writeEntry( "TemplateTab", d->m_jwidget->activePageIndex() );
+ grp.writePathEntry( "TemplateName", d->m_templateName );
+ grp.writePathEntry( "FullTemplateName", d->m_fullTemplateName);
+ }
+
+ if (d->m_nodiag)
+ {
+ // The checkbox m_nodiag is in tri-state mode for new documents
+ // fixes bug:77542
+ if (d->m_nodiag->state() == QButton::On) {
+ grp.writeEntry( "NoStartDlg", "yes");
+ }
+ else if (d->m_nodiag->state() == QButton::Off) {
+ grp.writeEntry( "NoStartDlg", "no");
+ }
+ }
+ }
+ else
+ {
+ kdWarning(30003) << "Unsupported template chooser result: " << d->m_returnType << endl;
+ grp.writeEntry( "LastReturnType", QString::null );
+ }
+ KDialogBase::slotOk();
+ }
+}
+
+/*================================================================*/
+// private
+bool KoTemplateChooseDia::collectInfo()
+{
+
+
+ // to determine what tab is selected in "Everything" mode
+ bool newTabSelected = false;
+ if ( d->m_dialogType == Everything)
+ if ( d->tabWidget->currentPage() == d->newTab )
+ newTabSelected = true;
+
+ // is it a template or a file ?
+ if ( d->m_dialogType==OnlyTemplates || newTabSelected )
+ {
+ // a template is chosen
+ if (d->m_templateName.length() > 0)
+ d->m_returnType = Template;
+ else
+ d->m_returnType=Empty;
+
+ return true;
+ }
+ else if ( d->m_dialogType != OnlyTemplates )
+ {
+ // a file is chosen
+ if (d->m_dialogType == Everything && d->tabWidget->currentPage() == d->recentTab)
+ {
+ // Recent file
+ KFileItem * item = d->m_recent->currentFileItem();
+ if (! item)
+ return false;
+ KURL url = item->url();
+ if(url.isLocalFile() && !QFile::exists(url.path()))
+ {
+ KMessageBox::error( this, i18n( "The file %1 does not exist." ).arg( url.path() ) );
+ return false;
+ }
+ d->m_fullTemplateName = url.url();
+ d->m_returnType = File;
+ }
+ else
+ {
+ // Existing file from file dialog
+ if ( !d->m_filedialog->slotOkCalled() )
+ d->m_filedialog->slotOk();
+ KURL url = d->m_filedialog->currentURL();
+ d->m_fullTemplateName = url.url();
+ d->m_returnType = File;
+ return d->m_filedialog->checkURL();
+ }
+ return true;
+ }
+
+ d->m_returnType=Empty;
+ return false;
+}
+
+/*================================================================*/
+//private
+QString KoTemplateChooseDia::descriptionText(const QString &name, const QString &description)
+{
+ QString descrText(i18n("Name:"));
+ descrText += " " + name;
+ descrText += "\n";
+ descrText += i18n("Description:");
+ if (description.isEmpty())
+ descrText += " " + i18n("No description available");
+ else
+ descrText += " " + description;
+ return descrText;
+}
+
+/*================================================================*/
+
+QIconViewItem * KoTCDIconCanvas::load( KoTemplateGroup *group, const QString& name, KInstance* instance )
+{
+ QIconViewItem * itemtoreturn = 0;
+
+ for (KoTemplate *t=group->first(); t!=0L; t=group->next()) {
+ if (t->isHidden())
+ continue;
+ QIconViewItem *item = new KoTCDIconViewItem(
+ this,
+ t->name(),
+ t->loadPicture(instance),
+ t->description(),
+ t->file());
+
+ if (name == t->name())
+ {
+ itemtoreturn = item;
+ }
+
+ item->setKey(t->name());
+ item->setDragEnabled(false);
+ item->setDropEnabled(false);
+ }
+
+ return itemtoreturn;
+}
+
+/*================================================================*/
+
+KoTCDRecentFilesIconView::~KoTCDRecentFilesIconView()
+{
+ removeToolTip();
+}
+
+void KoTCDRecentFilesIconView::showToolTip( QIconViewItem* item )
+{
+ removeToolTip();
+ if ( !item )
+ return;
+
+ // Mostly duplicated from KFileIconView, because it only shows tooltips
+ // for truncated icon texts, and we want tooltips on all icons,
+ // with the full path...
+ // KFileIconView would need a virtual method for deciding if a tooltip should be shown,
+ // and another one for deciding what's the text of the tooltip...
+ const KFileItem *fi = ( (KFileIconViewItem*)item )->fileInfo();
+ QString toolTipText = fi->url().prettyURL( 0, KURL::StripFileProtocol );
+ toolTip = new QLabel( QString::fromLatin1(" %1 ").arg(toolTipText), 0,
+ "myToolTip",
+ WStyle_StaysOnTop | WStyle_Customize | WStyle_NoBorder | WStyle_Tool | WX11BypassWM );
+ toolTip->setFrameStyle( QFrame::Plain | QFrame::Box );
+ toolTip->setLineWidth( 1 );
+ toolTip->setAlignment( AlignLeft | AlignTop );
+ toolTip->move( QCursor::pos() + QPoint( 14, 14 ) );
+ toolTip->adjustSize();
+ QRect screen = QApplication::desktop()->screenGeometry(
+ QApplication::desktop()->screenNumber(QCursor::pos()));
+ if (toolTip->x()+toolTip->width() > screen.right()) {
+ toolTip->move(toolTip->x()+screen.right()-toolTip->x()-toolTip->width(), toolTip->y());
+ }
+ if (toolTip->y()+toolTip->height() > screen.bottom()) {
+ toolTip->move(toolTip->x(), screen.bottom()-toolTip->y()-toolTip->height()+toolTip->y());
+ }
+ toolTip->setFont( QToolTip::font() );
+ toolTip->setPalette( QToolTip::palette(), TRUE );
+ toolTip->show();
+}
+
+void KoTCDRecentFilesIconView::removeToolTip()
+{
+ delete toolTip;
+ toolTip = 0;
+}
+
+void KoTCDRecentFilesIconView::hideEvent( QHideEvent *ev )
+{
+ removeToolTip();
+ KFileIconView::hideEvent( ev );
+}
+
+#include "KoTemplateChooseDia.moc"
diff --git a/lib/kofficeui/KoTemplateChooseDia.h b/lib/kofficeui/KoTemplateChooseDia.h
new file mode 100644
index 00000000..41389b20
--- /dev/null
+++ b/lib/kofficeui/KoTemplateChooseDia.h
@@ -0,0 +1,250 @@
+/*
+ This file is part of the KDE project
+ Copyright (C) 1998, 1999 Reginald Stadlbauer <reggie@kde.org>
+ 2000, 2001 Werner Trobin <trobin@kde.org>
+ 2002, 2003 Thomas Nagy <tnagy@eleve.emn.fr>
+ 2004 David Faure <faure@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef koTemplateChooseDia_h
+#define koTemplateChooseDia_h
+
+#include <kdialogbase.h>
+#include <kicondialog.h>
+#include <kiconview.h>
+#include <koffice_export.h>
+
+// KoTCD : KoTemplateChooseDia
+
+class KoTCDIconViewItem;
+class KoTemplateTree;
+class KoTemplateGroup;
+class QGridLayout;
+
+/**
+ * Our reimplementation of KIconCanvas used within the template-chooser dialog.
+ * @internal
+ */
+class KoTCDIconCanvas : public KIconCanvas
+{
+ Q_OBJECT
+ public:
+ KoTCDIconCanvas( QWidget *parent = 0, const char *name = 0L )
+ : KIconCanvas( parent, name ) {}
+
+ bool isCurrentValid() { return currentItem(); }
+ QIconViewItem * load(KoTemplateGroup *group, const QString& name, KInstance* instance);
+
+ protected:
+ virtual void keyPressEvent( QKeyEvent *e ) {
+ if ( e->key() == Key_Return || e->key() == Key_Enter )
+ e->ignore();
+ else
+ KIconCanvas::keyPressEvent( e );
+ }
+};
+
+/// @internal
+class KoTCDIconViewItem : public KIconViewItem
+{
+ public:
+ KoTCDIconViewItem(QIconView *parent=0)
+ : KIconViewItem ( parent )
+ {}
+
+ KoTCDIconViewItem(QIconView *parent=0, const QString &text=0, const QPixmap &icon=0,
+ const QString &descr=0, const QString &fullname=0)
+ : KIconViewItem(parent, text, icon)
+ {
+ m_descr = descr;
+ m_full = fullname;
+ }
+
+ QString getDescr() const { return m_descr; }
+ QString getFName() const { return m_full; }
+
+ private :
+ QString m_descr;
+ QString m_full;
+
+};
+
+#include <kfileiconview.h>
+#include <qlabel.h>
+/**
+ * Our reimplementation of KFileIconView used as the "recent files" view
+ * within the template-chooser dialog.
+ * @internal
+ */
+class KoTCDRecentFilesIconView : public KFileIconView {
+ Q_OBJECT
+ public:
+ KoTCDRecentFilesIconView( QWidget* parent, const char* name ) :
+ KFileIconView( parent, name ), toolTip(0)
+ {
+ connect( this, SIGNAL( onItem( QIconViewItem * ) ),
+ SLOT( showToolTip( QIconViewItem * ) ) );
+ connect( this, SIGNAL( onViewport() ),
+ SLOT( removeToolTip() ) );
+ }
+ virtual ~KoTCDRecentFilesIconView();
+ protected:
+ /**
+ * Reimplemented to remove an eventual tooltip
+ */
+ virtual void hideEvent( QHideEvent * );
+
+ private slots:
+ void showToolTip( QIconViewItem* );
+ void removeToolTip();
+ private:
+ QLabel* toolTip;
+};
+
+class KInstance;
+class KoTemplateChooseDiaPrivate;
+
+/**
+ * This class is used to show the template dialog
+ * on startup. Unless you need something special, you should use the static
+ * method choose().
+ *
+ * @short The template choose dialog
+ * @author Reginald Stadlbauer <reggie@kde.org>
+ * @author Werner Trobin <trobin@kde.org>
+ */
+class KOFFICEUI_EXPORT KoTemplateChooseDia : public KDialogBase
+{
+ Q_OBJECT
+
+public:
+ /**
+ * The Dialog returns one of these values depending
+ * on the input of the user.
+ * Cancel = The user pressed 'Cancel'
+ * Template = The user selected a template
+ * File = The user has chosen a file
+ * Empty = The user selected "Empty document"
+ */
+ enum ReturnType { Cancel, Template, File, Empty };
+ /**
+ * To configure the dialog you have to use this enum.
+ * Everything = Show templates and the rest of the dialog
+ * OnlyTemplates = Show only the templates
+ * NoTemplates = Just guess :)
+ */
+ enum DialogType { Everything, OnlyTemplates, NoTemplates };
+
+ ~KoTemplateChooseDia();
+
+ /**
+ * This is the static method you'll normally use to show the
+ * dialog.
+ *
+ * @param instance the KInstance of your app
+ * The native mimetype is retrieved from the (desktop file of) that instance.
+ * @param file this is the filename which is returned to your app
+ * More precisely, it's a url (to give to KURL) if ReturnType is File
+ * and it's a path (to open directly) if ReturnType is Template
+ *
+ * @param dialogType the type of the dialog
+ * @param templateType the template type of your application (see kword or
+ * kpresenter for details)
+ * @param parent pointer to parent widget
+ * @return The return type (see above)
+ */
+ static ReturnType choose(KInstance* instance, QString &file,
+ const DialogType &dialogType,
+ const QCString& templateType,
+ QWidget* parent);
+
+private:
+ /// Ditto, with extraNativeMimeTypes added
+ static ReturnType choose(KInstance* instance, QString &file,
+ const QCString &format,
+ const QString &nativeName,
+ const QStringList& extraNativeMimeTypes,
+ const DialogType &dialogType=Everything,
+ const QCString& templateType="",
+ QWidget* parent = 0);
+public:
+
+ /**
+ * Method to get the current template
+ */
+ QString getTemplate() const;
+ /**
+ * Method to get the "full" template (path+template)
+ */
+ QString getFullTemplate() const;
+ /**
+ * The ReturnType (call this one after exec())
+ */
+ ReturnType getReturnType() const;
+ /**
+ * The dialogType - normally you won't need this one
+ */
+ DialogType getDialogType() const;
+
+protected slots:
+ /**
+ * Activated when the Ok button has been clicked.
+ */
+ virtual void slotOk();
+
+private:
+ /**
+ *
+ * @param parent parent the parent of the dialog
+ * @param name the Qt internal name
+ * @param instance the KInstance of your app
+ * @param format is the mimetype of the app (e.g. application/x-kspread)
+ * @param nativeName is the name of your app (e.g KSpread)
+ * @param dialogType the type of the dialog
+ * @param templateType the template type of your application (see kword or
+ * kpresenter for details)
+ *
+ * @return The return type (see above)
+ */
+ KoTemplateChooseDia(QWidget *parent, const char *name, KInstance* instance,
+ const QCString &format,
+ const QString &nativeName,
+ const QStringList &extraNativeMimeTypes,
+ const DialogType &dialogType=Everything,
+ const QCString& templateType="");
+
+private:
+ KoTemplateChooseDiaPrivate *d;
+
+ QString descriptionText(const QString &name, const QString &description);
+ void setupDialog();
+ void setupTemplateDialog(QWidget * widgetbase, QGridLayout * layout);
+ void setupFileDialog(QWidget * widgetbase, QGridLayout * layout);
+ void setupRecentDialog(QWidget * widgetbase, QGridLayout * layout);
+ bool collectInfo();
+ bool noStartupDlg() const;
+
+private slots:
+
+ void chosen(QIconViewItem *);
+ void currentChanged( QIconViewItem * );
+ void recentSelected( QIconViewItem * );
+};
+
+#endif
+
diff --git a/lib/kofficeui/KoTemplateCreateDia.cpp b/lib/kofficeui/KoTemplateCreateDia.cpp
new file mode 100644
index 00000000..0e89bb99
--- /dev/null
+++ b/lib/kofficeui/KoTemplateCreateDia.cpp
@@ -0,0 +1,497 @@
+/*
+ This file is part of the KDE project
+ Copyright (C) 1998, 1999 Reginald Stadlbauer <reggie@kde.org>
+ 2000 Werner Trobin <trobin@kde.org>
+ Copyright (C) 2004 Nicolas GOUTTE <goutte@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#include <KoTemplateCreateDia.h>
+
+#include <qfile.h>
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qgroupbox.h>
+#include <qradiobutton.h>
+#include <qpushbutton.h>
+#include <qheader.h>
+#include <qcheckbox.h>
+#include <qtooltip.h>
+
+#include <ktempfile.h>
+#include <klineedit.h>
+#include <klistview.h>
+#include <klocale.h>
+#include <KoTemplates.h>
+#include <kicondialog.h>
+#include <kinputdialog.h>
+#include <kmessagebox.h>
+#include <kimageio.h>
+#include <kstandarddirs.h>
+#include <kdebug.h>
+#include <kio/netaccess.h>
+#include <kiconloader.h>
+#include <kaboutdata.h>
+#include <kconfigbase.h>
+#include <kconfig.h>
+
+#include <stdlib.h>
+#include <kinstance.h>
+
+
+class KoTemplateCreateDiaPrivate {
+public:
+ KoTemplateCreateDiaPrivate( QWidget* /*parent*/, KInstance * instance)
+ : m_instance( instance ), m_tempFile( QString::null, ".png" )
+ {
+ m_tree=0L;
+ m_name=0L;
+ m_default=0L;
+ m_custom=0L;
+ m_select=0L;
+ m_preview=0L;
+ m_groups=0L;
+ m_add=0L;
+ m_remove=0L;
+ m_defaultTemplate=0L;
+ m_tempFile.setAutoDelete( true );
+ }
+ ~KoTemplateCreateDiaPrivate() {
+ delete m_tree;
+ }
+
+ KoTemplateTree *m_tree;
+ KLineEdit *m_name;
+ QRadioButton *m_default, *m_custom;
+ QPushButton *m_select;
+ QLabel *m_preview;
+ QString m_customFile;
+ QPixmap m_customPixmap;
+ KListView *m_groups;
+ QPushButton *m_add, *m_remove;
+ QCheckBox *m_defaultTemplate;
+ KInstance *m_instance;
+ bool m_changed;
+ /// Temp file for remote picture file
+ KTempFile m_tempFile;
+};
+
+
+/****************************************************************************
+ *
+ * Class: koTemplateCreateDia
+ *
+ ****************************************************************************/
+
+KoTemplateCreateDia::KoTemplateCreateDia( const QCString &templateType, KInstance *instance,
+ const QString &file, const QPixmap &pix, QWidget *parent ) :
+ KDialogBase( parent, "template create dia", true, i18n( "Create Template" ),
+ KDialogBase::Ok | KDialogBase::Cancel, KDialogBase::Ok ), m_file(file), m_pixmap(pix) {
+
+ d=new KoTemplateCreateDiaPrivate( parent, instance );
+
+ QFrame *mainwidget=makeMainWidget();
+ QHBoxLayout *mbox=new QHBoxLayout(mainwidget, 0, KDialogBase::spacingHint());
+ QVBoxLayout *leftbox=new QVBoxLayout(mbox);
+
+ QLabel *label=new QLabel(i18n("Name:"), mainwidget);
+ leftbox->addSpacing(label->fontMetrics().height()/2);
+ QHBoxLayout *namefield=new QHBoxLayout(leftbox);
+ namefield->addWidget(label);
+ d->m_name=new KLineEdit(mainwidget);
+ d->m_name->setFocus();
+ connect(d->m_name, SIGNAL(textChanged(const QString &)),
+ this, SLOT(slotNameChanged(const QString &)));
+ namefield->addWidget(d->m_name);
+
+ label=new QLabel(i18n("Group:"), mainwidget);
+ leftbox->addWidget(label);
+ d->m_groups=new KListView(mainwidget);
+ leftbox->addWidget(d->m_groups);
+ d->m_groups->addColumn("");
+ d->m_groups->header()->hide();
+ d->m_groups->setRootIsDecorated(true);
+ d->m_groups->setSorting(0);
+
+ d->m_tree=new KoTemplateTree(templateType, instance, true);
+ fillGroupTree();
+ d->m_groups->sort();
+
+ QHBoxLayout *bbox=new QHBoxLayout(leftbox);
+ d->m_add=new QPushButton(i18n("&Add Group..."), mainwidget);
+ connect(d->m_add, SIGNAL(clicked()), this, SLOT(slotAddGroup()));
+ bbox->addWidget(d->m_add);
+ d->m_remove=new QPushButton(i18n("&Remove"), mainwidget);
+ connect(d->m_remove, SIGNAL(clicked()), this, SLOT(slotRemove()));
+ bbox->addWidget(d->m_remove);
+
+ QVBoxLayout *rightbox=new QVBoxLayout(mbox);
+ QGroupBox *pixbox=new QGroupBox(i18n("Picture"), mainwidget);
+ rightbox->addWidget(pixbox);
+ QVBoxLayout *pixlayout=new QVBoxLayout(pixbox, KDialogBase::marginHint(),
+ KDialogBase::spacingHint());
+ pixlayout->addSpacing(pixbox->fontMetrics().height()/2);
+ pixlayout->addStretch(1);
+ d->m_default=new QRadioButton(i18n("&Default"), pixbox);
+ d->m_default->setChecked(true);
+ connect(d->m_default, SIGNAL(clicked()), this, SLOT(slotDefault()));
+ pixlayout->addWidget(d->m_default);
+ QHBoxLayout *custombox=new QHBoxLayout(pixlayout);
+ d->m_custom=new QRadioButton(i18n("Custom"), pixbox);
+ d->m_custom->setChecked(false);
+ connect(d->m_custom, SIGNAL(clicked()), this, SLOT(slotCustom()));
+ custombox->addWidget(d->m_custom);
+ d->m_select=new QPushButton(i18n("&Select..."), pixbox);
+ connect(d->m_select, SIGNAL(clicked()), this, SLOT(slotSelect()));
+ custombox->addWidget(d->m_select, 1);
+ custombox->addStretch(1);
+ pixlayout->addStretch(1);
+ label=new QLabel(i18n("Preview:"), pixbox);
+ pixlayout->addWidget(label);
+ QHBoxLayout *previewbox=new QHBoxLayout(pixlayout);
+ previewbox->addStretch(10);
+ d->m_preview=new QLabel(pixbox); // setPixmap() -> auto resize?
+ previewbox->addWidget(d->m_preview);
+ previewbox->addStretch(10);
+ pixlayout->addStretch(8);
+
+ d->m_defaultTemplate = new QCheckBox( i18n("Use the new template as default"), mainwidget );
+ d->m_defaultTemplate->setChecked( true );
+ QToolTip::add( d->m_defaultTemplate, i18n("Use the new template every time %1 starts").arg(instance->aboutData()->programName() ) );
+ rightbox->addWidget( d->m_defaultTemplate );
+
+ enableButtonOK(false);
+ d->m_changed=false;
+ updatePixmap();
+
+ connect(d->m_groups,SIGNAL( selectionChanged()),this,SLOT(slotSelectionChanged()));
+
+ d->m_remove->setEnabled(d->m_groups->currentItem());
+}
+
+KoTemplateCreateDia::~KoTemplateCreateDia() {
+ delete d;
+}
+
+void KoTemplateCreateDia::slotSelectionChanged()
+{
+ const QListViewItem* item = d->m_groups->currentItem();
+ d->m_remove->setEnabled( item );
+ if ( ! item )
+ return;
+
+ if ( item->depth() > 0 )
+ {
+ d->m_name->setText( item->text( 0 ) );
+ }
+}
+
+void KoTemplateCreateDia::createTemplate( const QCString &templateType, KInstance *instance,
+ const QString &file, const QPixmap &pix, QWidget *parent ) {
+
+ KoTemplateCreateDia *dia = new KoTemplateCreateDia( templateType, instance, file, pix, parent );
+ dia->exec();
+ delete dia;
+}
+
+void KoTemplateCreateDia::slotOk() {
+
+ // get the current item, if there is one...
+ QListViewItem *item=d->m_groups->currentItem();
+ if(!item)
+ item=d->m_groups->firstChild();
+ if(!item) { // safe :)
+ d->m_tree->writeTemplateTree();
+ KDialogBase::slotCancel();
+ return;
+ }
+ // is it a group or a template? anyway - get the group :)
+ if(item->depth()!=0)
+ item=item->parent();
+ if(!item) { // *very* safe :P
+ d->m_tree->writeTemplateTree();
+ KDialogBase::slotCancel();
+ return;
+ }
+
+ KoTemplateGroup *group=d->m_tree->find(item->text(0));
+ if(!group) { // even safer
+ d->m_tree->writeTemplateTree();
+ KDialogBase::slotCancel();
+ return;
+ }
+
+ if(d->m_name->text().isEmpty()) {
+ d->m_tree->writeTemplateTree();
+ KDialogBase::slotCancel();
+ return;
+ }
+
+ // copy the tmp file and the picture the app provides
+ QString dir=d->m_tree->instance()->dirs()->saveLocation(d->m_tree->templateType());
+ dir+=group->name();
+ QString templateDir=dir+"/.source/";
+ QString iconDir=dir+"/.icon/";
+
+ QString file=KoTemplates::stripWhiteSpace(d->m_name->text());
+ QString tmpIcon=".icon/"+file;
+ tmpIcon+=".png";
+ QString icon=iconDir+file;
+ icon+=".png";
+
+ // try to find the extension for the template file :P
+ const int pos = m_file.findRev( '.' );
+ QString ext;
+ if ( pos > -1 )
+ ext = m_file.mid( pos );
+ else
+ kdWarning(30004) << "Template extension not found!" << endl;
+
+ KURL dest;
+ dest.setPath(templateDir+file+ext);
+ if ( QFile::exists( dest.prettyURL(0, KURL::StripFileProtocol) ) )
+ {
+ do
+ {
+ file.prepend( '_' );
+ dest.setPath( templateDir + file + ext );
+ tmpIcon=".icon/"+file+".png";
+ icon=iconDir+file+".png";
+ }
+ while ( KIO::NetAccess::exists( dest, true, this ) );
+ }
+ bool ignore = false;
+ kdDebug(30004) << "Trying to create template: " << d->m_name->text() << "URL=" << ".source/"+file+ext << " ICON=" << tmpIcon << endl;
+ KoTemplate *t=new KoTemplate(d->m_name->text(), QString::null, ".source/"+file+ext, tmpIcon, "", "", false, true);
+ if(!group->add(t)) {
+ KoTemplate *existingTemplate=group->find(d->m_name->text());
+ if(existingTemplate && !existingTemplate->isHidden()) {
+ if(KMessageBox::warningYesNo(this, i18n("Do you really want to overwrite"
+ " the existing '%1' template?").
+ arg(existingTemplate->name()))==KMessageBox::Yes)
+ group->add(t, true);
+ else
+ {
+ delete t;
+ return;
+ }
+ }
+ else
+ ignore = true;
+ }
+
+ if(!KStandardDirs::makeDir(templateDir) || !KStandardDirs::makeDir(iconDir)) {
+ d->m_tree->writeTemplateTree();
+ KDialogBase::slotCancel();
+ return;
+ }
+
+ KURL orig;
+ orig.setPath( m_file );
+ // don't overwrite the hidden template file with a new non-hidden one
+ if ( !ignore )
+ {
+ // copy the template file
+ KIO::NetAccess::file_copy( orig, dest, -1, true, false, this );
+
+ // save the picture
+ if(d->m_default->isChecked() && !m_pixmap.isNull())
+ m_pixmap.save(icon, "PNG");
+ else if(!d->m_customPixmap.isNull())
+ d->m_customPixmap.save(icon, "PNG");
+ else
+ kdWarning(30004) << "Could not save the preview picture!" << endl;
+ }
+
+ // if there's a .directory file, we copy this one, too
+ bool ready=false;
+ QStringList tmp=group->dirs();
+ for(QStringList::ConstIterator it=tmp.begin(); it!=tmp.end() && !ready; ++it) {
+ if((*it).contains(dir)==0) {
+ orig.setPath( (*it)+".directory" );
+ // Check if we can read the file
+ if( KIO::NetAccess::exists(orig, true, this) ) {
+ dest.setPath( dir+"/.directory" );
+ // We copy the file with overwrite
+ KIO::NetAccess::file_copy( orig, dest, -1, true, false, this );
+ ready=true;
+ }
+ }
+ }
+
+ d->m_tree->writeTemplateTree();
+
+ if ( d->m_defaultTemplate->isChecked() )
+ {
+ KConfigGroup grp( d->m_instance->config(), "TemplateChooserDialog" );
+ grp.writeEntry( "LastReturnType", "Template" );
+ grp.writePathEntry( "FullTemplateName", dir + "/" + t->file() );
+ grp.writePathEntry( "AlwaysUseTemplate", dir + "/" + t->file() );
+ }
+ KDialogBase::slotOk();
+}
+
+void KoTemplateCreateDia::slotDefault() {
+
+ d->m_default->setChecked(true);
+ d->m_custom->setChecked(false);
+ updatePixmap();
+}
+
+void KoTemplateCreateDia::slotCustom() {
+
+ d->m_default->setChecked(false);
+ d->m_custom->setChecked(true);
+ if(d->m_customFile.isEmpty())
+ slotSelect();
+ else
+ updatePixmap();
+}
+
+void KoTemplateCreateDia::slotSelect() {
+
+ d->m_default->setChecked(false);
+ d->m_custom->setChecked(true);
+
+ QString name = KIconDialog::getIcon();
+ if( name.isEmpty() ) {
+ if(d->m_customFile.isEmpty()) {
+ d->m_default->setChecked(true);
+ d->m_custom->setChecked(false);
+ }
+ return;
+ }
+ // ### TODO: do a better remote loading without having to have d->m_tempFile
+ QString path = KGlobal::iconLoader()->iconPath(name, KIcon::Desktop);
+ d->m_customFile = path;
+ d->m_customPixmap=QPixmap();
+ updatePixmap();
+}
+
+void KoTemplateCreateDia::slotNameChanged(const QString &name) {
+
+ if( ( name.stripWhiteSpace().isEmpty() || !d->m_groups->firstChild() ) && !d->m_changed )
+ enableButtonOK(false);
+ else
+ enableButtonOK(true);
+}
+
+void KoTemplateCreateDia::slotAddGroup() {
+ bool ok=false;
+ const QString name ( KInputDialog::getText( i18n("Add Group"), i18n("Enter group name:"), QString::null, &ok, this ) );
+ if(!ok)
+ return;
+ KoTemplateGroup *group=d->m_tree->find(name);
+ if(group && !group->isHidden())
+ {
+ KMessageBox::information( this, i18n("This name is already used."), i18n("Add Group") );
+ return;
+ }
+ QString dir=d->m_tree->instance()->dirs()->saveLocation(d->m_tree->templateType());
+ dir+=name;
+ KoTemplateGroup *newGroup=new KoTemplateGroup(name, dir, 0, true);
+ d->m_tree->add(newGroup);
+ QListViewItem *item=new QListViewItem(d->m_groups, name);
+ d->m_groups->setCurrentItem(item);
+ d->m_groups->sort();
+ d->m_name->setFocus();
+ enableButtonOK(true);
+ d->m_changed=true;
+}
+
+void KoTemplateCreateDia::slotRemove() {
+
+ QListViewItem *item=d->m_groups->currentItem();
+ if(!item)
+ return;
+
+ QString what;
+ QString removed;
+ if (item->depth()==0) {
+ what = i18n("Do you really want to remove that group?");
+ removed = i18n("Remove Group");
+ } else {
+ what = i18n("Do you really want to remove that template?");
+ removed = i18n("Remove Template");
+ }
+
+ if(KMessageBox::warningContinueCancel(this, what,
+ removed,KGuiItem(i18n("&Delete"),"editdelete"))==KMessageBox::Cancel) {
+ d->m_name->setFocus();
+ return;
+ }
+
+ if(item->depth()==0) {
+ KoTemplateGroup *group=d->m_tree->find(item->text(0));
+ if(group)
+ group->setHidden(true);
+ }
+ else {
+ bool done=false;
+ for(KoTemplateGroup *g=d->m_tree->first(); g!=0L && !done; g=d->m_tree->next()) {
+ KoTemplate *t=g->find(item->text(0));
+ if(t) {
+ t->setHidden(true);
+ done=true;
+ }
+ }
+ }
+ delete item;
+ item=0L;
+ enableButtonOK(true);
+ d->m_name->setFocus();
+ d->m_changed=true;
+}
+
+void KoTemplateCreateDia::updatePixmap() {
+
+ if(d->m_default->isChecked() && !m_pixmap.isNull())
+ d->m_preview->setPixmap(m_pixmap);
+ else if(d->m_custom->isChecked() && !d->m_customFile.isEmpty()) {
+ if(d->m_customPixmap.isNull()) {
+ kdDebug(30004) << "Trying to load picture " << d->m_customFile << endl;
+ // use the code in KoTemplate to load the image... hacky, I know :)
+ KoTemplate t("foo", "bar", QString::null, d->m_customFile);
+ d->m_customPixmap=t.loadPicture(d->m_tree->instance());
+ }
+ else
+ kdWarning(30004) << "Trying to load picture" << endl;
+
+ if(!d->m_customPixmap.isNull())
+ d->m_preview->setPixmap(d->m_customPixmap);
+ else
+ d->m_preview->setText(i18n("Could not load picture."));
+ }
+ else
+ d->m_preview->setText(i18n("No picture available."));
+}
+
+void KoTemplateCreateDia::fillGroupTree() {
+
+ for(KoTemplateGroup *group=d->m_tree->first(); group!=0L; group=d->m_tree->next()) {
+ if(group->isHidden())
+ continue;
+ QListViewItem *groupItem=new QListViewItem(d->m_groups, group->name());
+ for(KoTemplate *t=group->first(); t!=0L; t=group->next()) {
+ if(t->isHidden())
+ continue;
+ (void)new QListViewItem(groupItem, t->name());
+ }
+ }
+}
+
+#include <KoTemplateCreateDia.moc>
diff --git a/lib/kofficeui/KoTemplateCreateDia.h b/lib/kofficeui/KoTemplateCreateDia.h
new file mode 100644
index 00000000..eb703592
--- /dev/null
+++ b/lib/kofficeui/KoTemplateCreateDia.h
@@ -0,0 +1,75 @@
+/*
+ This file is part of the KDE project
+ Copyright (C) 1998, 1999 Reginald Stadlbauer <reggie@kde.org>
+ 2000 Werner Trobin <trobin@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#ifndef koTemplateCreateDia_h
+#define koTemplateCreateDia_h
+
+#include <kdialogbase.h>
+#include <koffice_export.h>
+
+class QString;
+class QPixmap;
+class QWidget;
+class KInstance;
+class KLineEdit;
+class QListViewItem;
+class KoTemplateCreateDiaPrivate;
+
+/****************************************************************************
+ *
+ * Class: koTemplateCreateDia
+ *
+ ****************************************************************************/
+
+class KOFFICEUI_EXPORT KoTemplateCreateDia : public KDialogBase
+{
+ Q_OBJECT
+
+public:
+ KoTemplateCreateDia( const QCString &templateType, KInstance *instance,
+ const QString &file, const QPixmap &pix, QWidget *parent=0L );
+ ~KoTemplateCreateDia();
+
+ static void createTemplate( const QCString &templateType, KInstance *instance,
+ const QString &file, const QPixmap &pix, QWidget *parent=0L );
+
+protected:
+ void slotOk();
+
+private slots:
+ void slotDefault();
+ void slotCustom();
+ void slotSelect();
+ void slotNameChanged(const QString &name);
+
+ void slotAddGroup();
+ void slotRemove();
+ void slotSelectionChanged();
+private:
+ void updatePixmap();
+ void fillGroupTree();
+
+ QString m_file;
+ QPixmap m_pixmap;
+ KoTemplateCreateDiaPrivate *d;
+};
+
+#endif
diff --git a/lib/kofficeui/KoToolBox.cpp b/lib/kofficeui/KoToolBox.cpp
new file mode 100644
index 00000000..60a3a2bf
--- /dev/null
+++ b/lib/kofficeui/KoToolBox.cpp
@@ -0,0 +1,256 @@
+/*
+ Copyright (c) 2005 Boudewijn Rempt <boud@valdyas.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <qbuttongroup.h>
+#include <qnamespace.h>
+#include <qtoolbutton.h>
+#include <qlabel.h>
+#include <qtooltip.h>
+#include <qlayout.h>
+#include <qpixmap.h>
+#include <qtoolbar.h>
+#include <qdockwindow.h>
+
+#include <kdebug.h>
+#include <kparts/event.h>
+#include <klocale.h>
+#include <ktoolbar.h>
+#include <kiconloader.h>
+#include <kseparator.h>
+#include <kaction.h>
+#include <kactioncollection.h>
+#include <kactionclasses.h>
+
+#include <KoMainWindow.h>
+#include "KoToolBox.h"
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+KoToolBox::KoToolBox( KMainWindow *mainWin, const char* name, KInstance* instance, int numberOfTooltypes )
+ : KToolBar( mainWin, Qt::DockLeft, false, name, true, true), m_instance(instance)
+{
+ setFullSize( false );
+ setMargin(2);
+
+ m_buttonGroup = new QButtonGroup( 0L );
+ m_buttonGroup->setExclusive( true );
+ connect( m_buttonGroup, SIGNAL( pressed( int ) ), this, SLOT( slotButtonPressed( int ) ) );
+
+ m_tools.setAutoDelete( true );
+ // Create separate lists for the various sorts of tools
+ for (int i = 0; i < numberOfTooltypes ; ++i) {
+ ToolList * tl = new ToolList();
+ m_tools.append(tl);
+ }
+}
+
+KoToolBox::~KoToolBox()
+{
+ delete m_buttonGroup;
+}
+
+
+void KoToolBox::slotPressButton( int id )
+{
+ m_buttonGroup->setButton( id );
+ slotButtonPressed( id );
+}
+
+void KoToolBox::slotButtonPressed( int id )
+{
+ if( id != m_buttonGroup->selectedId() && m_buttonGroup->selected() ) {
+ m_buttonGroup->selected()->setDown( false );
+ }
+ m_idToActionMap.at(id)->activate();
+
+}
+
+void KoToolBox::registerTool( KAction *tool, int toolType, Q_UINT32 priority )
+{
+ uint prio = priority;
+ ToolList * tl = m_tools.at(toolType);
+ while( (*tl)[prio] ) prio++;
+ (*tl)[prio] = tool;
+}
+
+QToolButton *KoToolBox::createButton(QWidget * parent, const char* iconName, QString tooltip)
+{
+ QToolButton *button = new QToolButton(parent);
+
+ if ( iconName && *iconName ) {
+ QPixmap pixmap = BarIcon( iconName, m_instance );
+ button->setPixmap( pixmap );
+ button->setToggleButton( true );
+ }
+
+ if ( !tooltip.isEmpty() ) {
+ QToolTip::add( button, tooltip );
+ }
+ return button;
+}
+
+
+void KoToolBox::setupTools()
+{
+ int id = 0;
+ // Loop through tooltypes
+ for (uint i = 0; i < m_tools.count(); ++i) {
+ ToolList * tl = m_tools.at(i);
+
+ if (!tl) continue;
+ if (tl->isEmpty()) continue;
+
+ ToolArea *tools = new ToolArea( this );
+ ToolList::Iterator it;
+ for ( it = tl->begin(); it != tl->end(); ++it )
+ {
+ KAction *tool = it.data();
+ if(! tool)
+ continue;
+ QToolButton *bn = createButton(tools->getNextParent(), tool->icon().latin1(), tool->toolTip());
+ tools->add(bn);
+ m_buttonGroup->insert( bn, id++ );
+ m_idToActionMap.append( tool );
+ }
+ if (i < m_tools.count() -1) addSeparator();
+ m_toolBoxes.append(tools);
+ }
+ // select first (select tool)
+ m_buttonGroup->setButton( 0 );
+ m_numberOfButtons = id;
+}
+
+
+void KoToolBox::setOrientation ( Qt::Orientation o )
+{
+ if ( barPos() == Floating ) { // when floating, make it a standing toolbox.
+ o = o == Qt::Vertical ? Qt::Horizontal : Qt::Vertical;
+ }
+
+ QDockWindow::setOrientation( o );
+
+ for (uint i = 0; i < m_toolBoxes.count(); ++i) {
+ ToolArea *t = m_toolBoxes.at(i);
+ t->setOrientation(o);
+ }
+}
+
+
+void KoToolBox::enableTools(bool enable)
+{
+ if (m_tools.isEmpty()) return;
+ if (!m_buttonGroup) return;
+ if (m_numberOfButtons <= 0) return;
+
+ for (uint i = 0; i < m_tools.count(); ++i) {
+ ToolList * tl = m_tools.at(i);
+
+ if (!tl) continue;
+
+ ToolList::Iterator it;
+ for ( it = tl->begin(); it != tl->end(); ++it )
+ if (it != 0 && it.data())
+ it.data()->setEnabled(enable);
+ }
+ m_buttonGroup->setEnabled(enable);
+ for (Q_UINT32 i = 0; i < m_numberOfButtons; ++i) {
+ m_buttonGroup->find( i )->setEnabled( enable );
+ }
+}
+
+void KoToolBox::slotSetTool(const QString & toolname)
+{
+ for (uint i = 0; i < m_idToActionMap.count(); ++i) {
+ KAction * a = m_idToActionMap.at(i);
+ if (!a || a->name() != toolname) continue;
+
+ m_buttonGroup->setButton(i);
+ return;
+
+ }
+}
+
+
+// ----------------------------------------------------------------
+// class ToolArea
+
+
+ToolArea::ToolArea(QWidget *parent)
+ : QWidget(parent), m_left(true)
+{
+ m_layout = new QBoxLayout(this, QBoxLayout::LeftToRight, 0, 0, 0);
+ QWidget *w = new QWidget(this);
+ m_layout->addWidget(w);
+
+ QGridLayout *grid = new QGridLayout(w, 2, 2);
+ m_leftRow = new QWidget(w);
+ grid->addWidget(m_leftRow, 0, 0);
+ m_leftLayout = new QBoxLayout(m_leftRow, QBoxLayout::TopToBottom, 0, 1, 0);
+
+ w = new QWidget(this);
+ m_layout->addWidget(w);
+
+ grid = new QGridLayout(w, 2, 2);
+ m_rightRow = new QWidget(w);
+ grid->addWidget(m_rightRow, 0, 0);
+ m_rightLayout = new QBoxLayout(m_rightRow, QBoxLayout::TopToBottom, 0, 1, 0);
+}
+
+
+ToolArea::~ToolArea()
+{
+}
+
+
+void ToolArea::add(QWidget *button)
+{
+ if (m_left)
+ m_leftLayout->addWidget(button);
+ else
+ m_rightLayout->addWidget(button);
+ button->show();
+ m_left = !m_left;
+}
+
+
+QWidget* ToolArea::getNextParent()
+{
+ if (m_left)
+ return m_leftRow;
+ return m_rightRow;
+}
+
+
+void ToolArea::setOrientation ( Qt::Orientation o )
+{
+ QBoxLayout::Direction dir = (o != Qt::Horizontal
+ ? QBoxLayout::TopToBottom
+ : QBoxLayout::LeftToRight);
+ m_leftLayout->setDirection(dir);
+ m_rightLayout->setDirection(dir);
+
+ m_layout->setDirection(o == Qt::Horizontal
+ ? QBoxLayout::TopToBottom
+ : QBoxLayout::LeftToRight);
+}
+
+
+#include "KoToolBox.moc"
diff --git a/lib/kofficeui/KoToolBox.h b/lib/kofficeui/KoToolBox.h
new file mode 100644
index 00000000..81e1c751
--- /dev/null
+++ b/lib/kofficeui/KoToolBox.h
@@ -0,0 +1,119 @@
+/*
+ Copyright (c) 2005 Boudewijn Rempt <boud@valdyas.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+ */
+#ifndef _KO_TOOLBOX_H_
+#define _KO_TOOLBOX_H_
+
+#include <qtoolbutton.h>
+#include <qptrvector.h>
+#include <qtoolbar.h>
+#include <koffice_export.h>
+#include <ktoolbar.h>
+
+class QWidget;
+class KAction;
+class KMainWindow;
+class KDualColorButton;
+class QGridLayout;
+class ToolArea;
+
+
+/**
+ * KActionBox is a kind of super-specialized toolbox that can order
+ * tools according to type and priority.
+ *
+ * This is to a large extent a port of the Karbon vtoolbox -- with
+ * which it should be merged one day. However, it doesn't depend on a
+ * tool-like class, it aggregates actions.
+ */
+
+class KOFFICEUI_EXPORT KoToolBox : public KToolBar {
+
+ Q_OBJECT
+
+public:
+
+ KoToolBox( KMainWindow *mainWin, const char* name, KInstance* instance, int numberOfTooltypes);
+ virtual ~KoToolBox();
+
+ // Called by the toolcontroller for each tool. For every category,
+ // there is a separate list, and the tool is categorized correctly.
+ // The tool is not yet added to the widgets; call setupTools()
+ // to do that. We don't store the tool.
+ void registerTool(KAction * tool, int toolType, Q_UINT32 priority);
+
+ // Called when all tools have been added by the tool controller
+ void setupTools();
+
+public slots:
+
+ virtual void setOrientation ( Orientation o );
+ void slotButtonPressed( int id );
+ void slotPressButton( int id );
+
+ // Enables or disables all buttons and the corresponding actions.
+ void enableTools(bool enable);
+
+ void slotSetTool(const QString & toolname);
+
+private:
+
+ QToolButton * createButton(QWidget * parent, const char* iconName, QString tooltip);
+
+
+private:
+ Q_UINT32 m_numberOfButtons;
+
+ QButtonGroup * m_buttonGroup; // The invisible group of all toolbuttons, so only one can be active at a given time
+
+ QPtrList<ToolArea> m_toolBoxes; // For every ToolArea
+
+ typedef QMap< int, KAction*> ToolList; // The priority ordered list of tools for a certain tooltype
+
+ QPtrList<ToolList> m_tools;
+ QPtrList<KAction> m_idToActionMap; // Map the buttongroup id's to actions for easy activating.
+ KInstance* m_instance;
+};
+
+
+class ToolArea : public QWidget {
+
+public:
+ ToolArea(QWidget *parent);
+ ~ToolArea();
+
+ void setOrientation ( Qt::Orientation o );
+ void add(QWidget *button);
+
+ QWidget* getNextParent();
+
+private:
+ QPtrList<QWidget> m_children;
+ QBoxLayout *m_layout;
+
+ QWidget *m_leftRow;
+ QBoxLayout *m_leftLayout;
+
+ QWidget *m_rightRow;
+ QBoxLayout *m_rightLayout;
+
+ bool m_left;
+};
+
+
+#endif // _KO_TOOLBOX_H_
diff --git a/lib/kofficeui/KoTooluButton.cpp b/lib/kofficeui/KoTooluButton.cpp
new file mode 100644
index 00000000..c5e893d5
--- /dev/null
+++ b/lib/kofficeui/KoTooluButton.cpp
@@ -0,0 +1,858 @@
+/* This file is part of the KDE project
+ Copyright (C) 2002 Werner Trobin <trobin@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#include <qapplication.h>
+#include <qtooltip.h>
+#include <qpainter.h>
+#include <qdrawutil.h>
+#include <qpixmap.h>
+#include <qstyle.h>
+#include <qpopupmenu.h>
+
+#include <kglobalsettings.h>
+#include <ktoolbar.h>
+#include <KoTooluButton.h>
+#include <kcolordrag.h>
+#include <klocale.h>
+#include <kcolordialog.h>
+#include <kdebug.h>
+
+namespace {
+ // For the KoColorPanel
+ const int COLS = 15;
+ const int TILESIZE = 16;
+ // For the KoToolButton
+ int ARROW_WIDTH = 12;
+}
+
+KoColorPanel::KoColorPanel( QWidget* parent, const char* name ) :
+ QWidget( parent, name, WStaticContents | WRepaintNoErase | WResizeNoErase )
+{
+ setMouseTracking( true );
+ setAcceptDrops( true );
+ init();
+}
+
+KoColorPanel::~KoColorPanel()
+{
+}
+
+QSize KoColorPanel::sizeHint() const
+{
+ return minimumSizeHint();
+}
+
+QSize KoColorPanel::minimumSizeHint() const
+{
+ return QSize( COLS << 4, lines() << 4 );
+}
+
+QPopupMenu* KoColorPanel::createColorPopup( KoColorPanel::MenuStyle style, const QColor& defaultColor,
+ const QObject* receiver, const char* slot,
+ QWidget* parent, const char* name )
+{
+ QPopupMenu* menu = new QPopupMenu( parent, name );
+ KoColorPopupProxy* proxy = 0;
+
+ if ( defaultColor.isValid() ) {
+ QPixmap pixmap( 12, 12 );
+ QPainter p( &pixmap );
+ p.fillRect( 0, 0, 12, 12, defaultColor );
+ p.end();
+ proxy = new KoColorPopupProxy( defaultColor, 0, menu, "color proxy" );
+ connect( proxy, SIGNAL( colorSelected( const QColor& ) ), receiver, slot );
+ menu->insertItem( QIconSet( pixmap ), i18n( "Default Color" ), proxy, SLOT( slotDefaultColor() ) );
+ menu->insertSeparator();
+ }
+
+ KoColorPanel* panel = new KoColorPanel( menu, "default colors" );
+ panel->insertDefaultColors();
+ connect( panel, SIGNAL( colorSelected( const QColor& ) ), receiver, slot );
+ menu->insertItem( panel );
+
+ if ( style == CustomColors ) {
+ menu->insertSeparator();
+ panel = new KoColorPanel( menu, "custom panel" );
+ connect( panel, SIGNAL( colorSelected( const QColor& ) ), receiver, slot );
+ menu->insertItem( panel );
+ if ( !proxy ) {
+ proxy = new KoColorPopupProxy( QColor(), panel, menu, "color proxy" );
+ connect( proxy, SIGNAL( colorSelected( const QColor& ) ), receiver, slot );
+ }
+ else
+ proxy->setRecentColorPanel( panel );
+ menu->insertSeparator();
+ menu->insertItem( i18n( "More Colors..." ), proxy, SLOT( slotMoreColors() ) );
+ }
+
+ return menu;
+}
+
+void KoColorPanel::clear()
+{
+ if ( m_colorMap.isEmpty() )
+ return;
+
+ QSize area( minimumSizeHint() );
+ m_colorMap.clear();
+ init();
+ updateGeometry();
+ erase( 0, 0, area.width(), area.height() );
+}
+
+void KoColorPanel::insertColor( const QColor& color )
+{
+ Position pos = m_nextPosition;
+ if ( insertColor( color, true ) ) // we want checking for external users
+ finalizeInsertion( pos );
+}
+
+void KoColorPanel::insertColor( const QColor& color, const QString& toolTip )
+{
+ Position pos = m_nextPosition;
+ if ( insertColor( color, toolTip, true ) ) // we want checking for external users
+ finalizeInsertion( pos );
+}
+
+void KoColorPanel::insertDefaultColors()
+{
+ if ( m_defaultsAdded )
+ return;
+ m_defaultsAdded = true;
+
+ int currentRow = m_nextPosition.y; // we have to repaint this row below
+
+ // Note: No checking for duplicates, so take care when you modify that list
+ insertColor(QColor( 255 , 0 , 0 ), i18n( "color", "Red" ), false);
+ insertColor(QColor( 255 , 165 , 0 ), i18n( "color", "Orange" ), false);
+ insertColor(QColor( 255 , 0 , 255 ), i18n( "color", "Magenta" ), false);
+ insertColor(QColor( 0 , 0 , 255 ), i18n( "color", "Blue" ), false);
+ insertColor(QColor( 0 , 255 , 255 ), i18n( "color", "Cyan" ), false);
+ insertColor(QColor( 0 , 255 , 0 ), i18n( "color", "Green" ), false);
+ insertColor(QColor( 255 , 255 , 0 ), i18n( "color", "Yellow" ), false);
+ insertColor(QColor( 165 , 42 , 42 ), i18n( "color", "Brown" ), false);
+ insertColor(QColor( 139 , 0 , 0 ), i18n( "color", "DarkRed" ), false);
+ insertColor(QColor( 255 , 140 , 0 ), i18n( "color", "DarkOrange" ), false);
+ insertColor(QColor( 139 , 0 , 139 ), i18n( "color", "DarkMagenta" ), false);
+ insertColor(QColor( 0 , 0 , 139 ), i18n( "color", "DarkBlue" ), false);
+ insertColor(QColor( 0 , 139 , 139 ), i18n( "color", "DarkCyan" ), false);
+ insertColor(QColor( 0 , 100 , 0 ), i18n( "color", "DarkGreen" ), false);
+ insertColor(QColor( 130 , 127 , 0 ), i18n( "color", "DarkYellow" ), false);
+ insertColor(QColor( 255 , 255 , 255 ), i18n( "color", "White" ), false);
+ // xgettext:no-c-format
+ insertColor(QColor( 229 , 229 , 229 ), i18n( "color", "Gray 90%" ), false);
+ // xgettext:no-c-format
+ insertColor(QColor( 204 , 204 , 204 ), i18n( "color", "Gray 80%" ), false);
+ // xgettext:no-c-format
+ insertColor(QColor( 178 , 178 , 178 ), i18n( "color", "Gray 70%" ), false);
+ // xgettext:no-c-format
+ insertColor(QColor( 153 , 153 , 153 ), i18n( "color", "Gray 60%" ), false);
+ // xgettext:no-c-format
+ insertColor(QColor( 127 , 127 , 127 ), i18n( "color", "Gray 50%" ), false);
+ // xgettext:no-c-format
+ insertColor(QColor( 102 , 102 , 102 ), i18n( "color", "Gray 40%" ), false);
+ // xgettext:no-c-format
+ insertColor(QColor( 76 , 76 , 76 ), i18n( "color", "Gray 30%" ), false);
+ // xgettext:no-c-format
+ insertColor(QColor( 51 , 51 , 51 ), i18n( "color", "Gray 20%" ), false);
+ // xgettext:no-c-format
+ insertColor(QColor( 25 , 25 , 25 ), i18n( "color", "Gray 10%" ), false);
+ insertColor(QColor( 0 , 0 , 0 ), i18n( "color", "Black" ), false);
+ insertColor(QColor( 255 , 255 , 240 ), i18n( "color", "Ivory" ), false);
+ insertColor(QColor( 255 , 250 , 250 ), i18n( "color", "Snow" ), false);
+ insertColor(QColor( 245 , 255 , 250 ), i18n( "color", "MintCream" ), false);
+ insertColor(QColor( 255 , 250 , 240 ), i18n( "color", "FloralWhite" ), false);
+ insertColor(QColor( 255 , 255 , 224 ), i18n( "color", "LightYellow" ), false);
+ insertColor(QColor( 240 , 255 , 255 ), i18n( "color", "Azure" ), false);
+ insertColor(QColor( 248 , 248 , 255 ), i18n( "color", "GhostWhite" ), false);
+ insertColor(QColor( 240 , 255 , 240 ), i18n( "color", "Honeydew" ), false);
+ insertColor(QColor( 255 , 245 , 238 ), i18n( "color", "Seashell" ), false);
+ insertColor(QColor( 240 , 248 , 255 ), i18n( "color", "AliceBlue" ), false);
+ insertColor(QColor( 255 , 248 , 220 ), i18n( "color", "Cornsilk" ), false);
+ insertColor(QColor( 255 , 240 , 245 ), i18n( "color", "LavenderBlush" ), false);
+ insertColor(QColor( 253 , 245 , 230 ), i18n( "color", "OldLace" ), false);
+ insertColor(QColor( 245 , 245 , 245 ), i18n( "color", "WhiteSmoke" ), false);
+ insertColor(QColor( 255 , 250 , 205 ), i18n( "color", "LemonChiffon" ), false);
+ insertColor(QColor( 224 , 255 , 255 ), i18n( "color", "LightCyan" ), false);
+ insertColor(QColor( 250 , 250 , 210 ), i18n( "color", "LightGoldenrodYellow" ), false);
+ insertColor(QColor( 250 , 240 , 230 ), i18n( "color", "Linen" ), false);
+ insertColor(QColor( 245 , 245 , 220 ), i18n( "color", "Beige" ), false);
+ insertColor(QColor( 255 , 239 , 213 ), i18n( "color", "PapayaWhip" ), false);
+ insertColor(QColor( 255 , 235 , 205 ), i18n( "color", "BlanchedAlmond" ), false);
+ insertColor(QColor( 250 , 235 , 215 ), i18n( "color", "AntiqueWhite" ), false);
+ insertColor(QColor( 255 , 228 , 225 ), i18n( "color", "MistyRose" ), false);
+ insertColor(QColor( 230 , 230 , 250 ), i18n( "color", "Lavender" ), false);
+ insertColor(QColor( 255 , 228 , 196 ), i18n( "color", "Bisque" ), false);
+ insertColor(QColor( 255 , 228 , 181 ), i18n( "color", "Moccasin" ), false);
+ insertColor(QColor( 255 , 222 , 173 ), i18n( "color", "NavajoWhite" ), false);
+ insertColor(QColor( 255 , 218 , 185 ), i18n( "color", "PeachPuff" ), false);
+ insertColor(QColor( 238 , 232 , 170 ), i18n( "color", "PaleGoldenrod" ), false);
+ insertColor(QColor( 245 , 222 , 179 ), i18n( "color", "Wheat" ), false);
+ insertColor(QColor( 220 , 220 , 220 ), i18n( "color", "Gainsboro" ), false);
+ insertColor(QColor( 240 , 230 , 140 ), i18n( "color", "Khaki" ), false);
+ insertColor(QColor( 175 , 238 , 238 ), i18n( "color", "PaleTurquoise" ), false);
+ insertColor(QColor( 255 , 192 , 203 ), i18n( "color", "Pink" ), false);
+ insertColor(QColor( 238 , 221 , 130 ), i18n( "color", "LightGoldenrod" ), false);
+ insertColor(QColor( 211 , 211 , 211 ), i18n( "color", "LightGray" ), false);
+ insertColor(QColor( 255 , 182 , 193 ), i18n( "color", "LightPink" ), false);
+ insertColor(QColor( 176 , 224 , 230 ), i18n( "color", "PowderBlue" ), false);
+ insertColor(QColor( 127 , 255 , 212 ), i18n( "color", "Aquamarine" ), false);
+ insertColor(QColor( 216 , 191 , 216 ), i18n( "color", "Thistle" ), false);
+ insertColor(QColor( 173 , 216 , 230 ), i18n( "color", "LightBlue" ), false);
+ insertColor(QColor( 152 , 251 , 152 ), i18n( "color", "PaleGreen" ), false);
+ insertColor(QColor( 255 , 215 , 0 ), i18n( "color", "Gold" ), false);
+ insertColor(QColor( 173 , 255 , 47 ), i18n( "color", "GreenYellow" ), false);
+ insertColor(QColor( 176 , 196 , 222 ), i18n( "color", "LightSteelBlue" ), false);
+ insertColor(QColor( 144 , 238 , 144 ), i18n( "color", "LightGreen" ), false);
+ insertColor(QColor( 221 , 160 , 221 ), i18n( "color", "Plum" ), false);
+ insertColor(QColor( 190 , 190 , 190 ), i18n( "color", "Gray" ), false);
+ insertColor(QColor( 222 , 184 , 135 ), i18n( "color", "BurlyWood" ), false);
+ insertColor(QColor( 135 , 206 , 250 ), i18n( "color", "LightSkyBlue" ), false);
+ insertColor(QColor( 255 , 160 , 122 ), i18n( "color", "LightSalmon" ), false);
+ insertColor(QColor( 135 , 206 , 235 ), i18n( "color", "SkyBlue" ), false);
+ insertColor(QColor( 210 , 180 , 140 ), i18n( "color", "Tan" ), false);
+ insertColor(QColor( 238 , 130 , 238 ), i18n( "color", "Violet" ), false);
+ insertColor(QColor( 244 , 164 , 96 ), i18n( "color", "SandyBrown" ), false);
+ insertColor(QColor( 233 , 150 , 122 ), i18n( "color", "DarkSalmon" ), false);
+ insertColor(QColor( 189 , 183 , 107 ), i18n( "color", "DarkKhaki" ), false);
+ insertColor(QColor( 127 , 255 , 0 ), i18n( "color", "Chartreuse" ), false);
+ insertColor(QColor( 169 , 169 , 169 ), i18n( "color", "DarkGray" ), false);
+ insertColor(QColor( 124 , 252 , 0 ), i18n( "color", "LawnGreen" ), false);
+ insertColor(QColor( 255 , 105 , 180 ), i18n( "color", "HotPink" ), false);
+ insertColor(QColor( 250 , 128 , 114 ), i18n( "color", "Salmon" ), false);
+ insertColor(QColor( 240 , 128 , 128 ), i18n( "color", "LightCoral" ), false);
+ insertColor(QColor( 64 , 224 , 208 ), i18n( "color", "Turquoise" ), false);
+ insertColor(QColor( 143 , 188 , 143 ), i18n( "color", "DarkSeaGreen" ), false);
+ insertColor(QColor( 218 , 112 , 214 ), i18n( "color", "Orchid" ), false);
+ insertColor(QColor( 102 , 205 , 170 ), i18n( "color", "MediumAquamarine" ), false);
+ insertColor(QColor( 255 , 127 , 80 ), i18n( "color", "Coral" ), false);
+ insertColor(QColor( 154 , 205 , 50 ), i18n( "color", "YellowGreen" ), false);
+ insertColor(QColor( 218 , 165 , 32 ), i18n( "color", "Goldenrod" ), false);
+ insertColor(QColor( 72 , 209 , 204 ), i18n( "color", "MediumTurquoise" ), false);
+ insertColor(QColor( 188 , 143 , 143 ), i18n( "color", "RosyBrown" ), false);
+ insertColor(QColor( 219 , 112 , 147 ), i18n( "color", "PaleVioletRed" ), false);
+ insertColor(QColor( 0 , 250 , 154 ), i18n( "color", "MediumSpringGreen" ), false);
+ insertColor(QColor( 255 , 99 , 71 ), i18n( "color", "Tomato" ), false);
+ insertColor(QColor( 0 , 255 , 127 ), i18n( "color", "SpringGreen" ), false);
+ insertColor(QColor( 205 , 133 , 63 ), i18n( "color", "Peru" ), false);
+ insertColor(QColor( 100 , 149 , 237 ), i18n( "color", "CornflowerBlue" ), false);
+ insertColor(QColor( 132 , 112 , 255 ), i18n( "color", "LightSlateBlue" ), false);
+ insertColor(QColor( 147 , 112 , 219 ), i18n( "color", "MediumPurple" ), false);
+ insertColor(QColor( 186 , 85 , 211 ), i18n( "color", "MediumOrchid" ), false);
+ insertColor(QColor( 95 , 158 , 160 ), i18n( "color", "CadetBlue" ), false);
+ insertColor(QColor( 0 , 206 , 209 ), i18n( "color", "DarkTurquoise" ), false);
+ insertColor(QColor( 0 , 191 , 255 ), i18n( "color", "DeepSkyBlue" ), false);
+ insertColor(QColor( 119 , 136 , 153 ), i18n( "color", "LightSlateGray" ), false);
+ insertColor(QColor( 184 , 134 , 11 ), i18n( "color", "DarkGoldenrod" ), false);
+ insertColor(QColor( 123 , 104 , 238 ), i18n( "color", "MediumSlateBlue" ), false);
+ insertColor(QColor( 205 , 92 , 92 ), i18n( "color", "IndianRed" ), false);
+ insertColor(QColor( 210 , 105 , 30 ), i18n( "color", "Chocolate" ), false);
+ insertColor(QColor( 60 , 179 , 113 ), i18n( "color", "MediumSeaGreen" ), false);
+ insertColor(QColor( 50 , 205 , 50 ), i18n( "color", "LimeGreen" ), false);
+ insertColor(QColor( 32 , 178 , 170 ), i18n( "color", "LightSeaGreen" ), false);
+ insertColor(QColor( 112 , 128 , 144 ), i18n( "color", "SlateGray" ), false);
+ insertColor(QColor( 30 , 144 , 255 ), i18n( "color", "DodgerBlue" ), false);
+ insertColor(QColor( 255 , 69 , 0 ), i18n( "color", "OrangeRed" ), false);
+ insertColor(QColor( 255 , 20 , 147 ), i18n( "color", "DeepPink" ), false);
+ insertColor(QColor( 70 , 130 , 180 ), i18n( "color", "SteelBlue" ), false);
+ insertColor(QColor( 106 , 90 , 205 ), i18n( "color", "SlateBlue" ), false);
+ insertColor(QColor( 107 , 142 , 35 ), i18n( "color", "OliveDrab" ), false);
+ insertColor(QColor( 65 , 105 , 225 ), i18n( "color", "RoyalBlue" ), false);
+ insertColor(QColor( 208 , 32 , 144 ), i18n( "color", "VioletRed" ), false);
+ insertColor(QColor( 153 , 50 , 204 ), i18n( "color", "DarkOrchid" ), false);
+ insertColor(QColor( 160 , 32 , 240 ), i18n( "color", "Purple" ), false);
+ insertColor(QColor( 105 , 105 , 105 ), i18n( "color", "DimGray" ), false);
+ insertColor(QColor( 138 , 43 , 226 ), i18n( "color", "BlueViolet" ), false);
+ insertColor(QColor( 160 , 82 , 45 ), i18n( "color", "Sienna" ), false);
+ insertColor(QColor( 199 , 21 , 133 ), i18n( "color", "MediumVioletRed" ), false);
+ insertColor(QColor( 176 , 48 , 96 ), i18n( "color", "Maroon" ), false);
+ insertColor(QColor( 46 , 139 , 87 ), i18n( "color", "SeaGreen" ), false);
+ insertColor(QColor( 85 , 107 , 47 ), i18n( "color", "DarkOliveGreen" ), false);
+ insertColor(QColor( 34 , 139 , 34 ), i18n( "color", "ForestGreen" ), false);
+ insertColor(QColor( 139 , 69 , 19 ), i18n( "color", "SaddleBrown" ), false);
+ insertColor(QColor( 148 , 0 , 211 ), i18n( "color", "DarkViolet" ), false);
+ insertColor(QColor( 178 , 34 , 34 ), i18n( "color", "FireBrick" ), false);
+ insertColor(QColor( 72 , 61 , 139 ), i18n( "color", "DarkSlateBlue" ), false);
+ insertColor(QColor( 47 , 79 , 79 ), i18n( "color", "DarkSlateGray" ), false);
+ insertColor(QColor( 25 , 25 , 112 ), i18n( "color", "MidnightBlue" ), false);
+ insertColor(QColor( 0 , 0 , 205 ), i18n( "color", "MediumBlue" ), false);
+ insertColor(QColor( 0 , 0 , 128 ), i18n( "color", "Navy" ), false);
+
+ finalizeInsertion( m_nextPosition ); // with a no-op paint() call as we repaint anyway
+ updateGeometry();
+ // we have to repaint the "old" current row explicitly due
+ // to WStaticContents
+ update( 0, currentRow << 4, COLS << 4, 16 );
+}
+
+void KoColorPanel::mousePressEvent( QMouseEvent* e )
+{
+ if ( e->button() == Qt::LeftButton )
+ m_pressedPos = e->pos();
+}
+
+void KoColorPanel::mouseReleaseEvent( QMouseEvent* )
+{
+ if ( isVisible() && parentWidget() && parentWidget()->inherits( "QPopupMenu" ) )
+ parentWidget()->close();
+ emit colorSelected( mapToColor( m_pressedPos ) );
+}
+
+void KoColorPanel::mouseMoveEvent( QMouseEvent* e )
+{
+ if ( e->state() & Qt::LeftButton ) {
+ QPoint p = m_pressedPos - e->pos();
+ if ( p.manhattanLength() > QApplication::startDragDistance() ) {
+ QColor color( mapToColor( m_pressedPos ) );
+ if ( color.isValid() ) {
+ KColorDrag *drag = new KColorDrag( color, this, name() );
+ drag->dragCopy();
+ }
+ }
+ }
+ else
+ updateFocusPosition( mapToPosition( e->pos() ) );
+}
+
+void KoColorPanel::paintEvent( QPaintEvent* e )
+{
+ int lns = lines();
+ int startRow, endRow, startCol, endCol;
+ paintArea( e->rect(), startRow, endRow, startCol, endCol );
+
+ QPainter p( this );
+
+ // First clear all the areas we won't paint on later (only if the widget isn't erased)
+ if ( !e->erased() ) {
+ // vertical rects
+ int tmp = TILESIZE * lns;
+ if ( startCol == 0 )
+ erase( 0, 0, 2, tmp );
+ if ( endCol == COLS )
+ erase( width() - 2, 0, 2, tmp );
+ else
+ erase( ( endCol << 4 ) - 2, 0, 2, tmp );
+ int i = startCol == 0 ? 1 : startCol;
+ for ( ; i < endCol; ++i )
+ erase( ( i << 4 ) - 2, 0, 4, tmp );
+
+ // horizontal rects
+ tmp = TILESIZE * COLS;
+ if ( startRow == 0 )
+ erase( 0, 0, tmp, 2 );
+ if ( endRow == lns )
+ erase( 0, height() - 2, tmp, 2 );
+ else
+ erase( 0, ( endRow << 4 ) - 2, tmp, 2 );
+ i = startRow == 0 ? 1 : startRow;
+ for ( ; i < endRow; ++i )
+ erase( 0, ( i << 4 ) - 2, tmp, 4 );
+ }
+
+ // The "active" element (if there is one)
+ if ( hasFocus() && m_focusPosition.x != -1 && m_focusPosition.y != -1 &&
+ mapFromPosition( m_focusPosition ).intersects( e->rect() ) )
+ style().drawPrimitive( QStyle::PE_Panel, &p, QRect( m_focusPosition.x << 4, m_focusPosition.y << 4, TILESIZE, TILESIZE ),
+ colorGroup(), QStyle::Style_Sunken | QStyle::Style_Enabled );
+
+ --lns; // Attention: We just avoid some lns - 1 statements
+
+ // ...all color tiles
+ if ( !m_colorMap.isEmpty() ) {
+ int currentRow = startRow, currentCol = startCol;
+ while ( currentRow < endRow && currentCol < endCol ) {
+ QMap<Position, QColor>::ConstIterator it = m_colorMap.find( Position( currentCol, currentRow ) );
+ if( it != m_colorMap.end() )
+ p.fillRect( ( currentCol << 4 ) + 2, ( currentRow << 4 ) + 2, 12, 12, it.data() );
+
+ // position of the next cell
+ ++currentCol;
+ if ( currentCol == endCol ) {
+ ++currentRow;
+ currentCol = startCol;
+ }
+ }
+ }
+
+ // clean up the last line (it's most likely that it's not totally filled)
+ if ( !e->erased() && endRow > lns ) {
+ int fields = m_colorMap.count() % COLS;
+ erase( fields << 4, lns * TILESIZE, ( COLS - fields ) << 4, 16 );
+ }
+}
+
+void KoColorPanel::keyPressEvent( QKeyEvent* e )
+{
+ Position newPos( validPosition( m_focusPosition ) );
+ if ( e->key() == Qt::Key_Up ) {
+ if ( newPos.y == 0 )
+ e->ignore();
+ else
+ --newPos.y;
+ }
+ else if ( e->key() == Qt::Key_Down ) {
+ if ( newPos < Position( m_colorMap.count() % COLS, lines() - 2 ) )
+ ++newPos.y;
+ else
+ e->ignore();
+ }
+ else if ( e->key() == Qt::Key_Left ) {
+ if ( newPos.x == 0 )
+ e->ignore();
+ else
+ --newPos.x;
+ }
+ else if ( e->key() == Qt::Key_Right ) {
+ if ( newPos.x < COLS - 1 && newPos < Position( m_colorMap.count() % COLS - 1, lines() - 1 ) )
+ ++newPos.x;
+ else
+ e->ignore();
+ }
+ else if ( e->key() == Qt::Key_Return ) {
+ if ( isVisible() && parentWidget() && parentWidget()->inherits( "QPopupMenu" ) )
+ parentWidget()->close();
+ emit colorSelected( mapToColor( m_focusPosition ) );
+ }
+ updateFocusPosition( newPos );
+}
+
+void KoColorPanel::focusInEvent( QFocusEvent* e )
+{
+ if ( !m_colorMap.isEmpty() && m_focusPosition.x == -1 && m_focusPosition.y == -1 ) {
+ m_focusPosition.x = 0;
+ m_focusPosition.y = 0;
+ }
+ QWidget::focusInEvent( e );
+}
+
+void KoColorPanel::dragEnterEvent( QDragEnterEvent* e )
+{
+ e->accept( KColorDrag::canDecode( e ) );
+}
+
+void KoColorPanel::dropEvent( QDropEvent* e )
+{
+ QColor color;
+ if ( KColorDrag::decode( e, color ) )
+ insertColor( color );
+}
+
+void KoColorPanel::finalizeInsertion( const Position& pos )
+{
+ paint( pos );
+
+ if ( !isFocusEnabled() )
+ setFocusPolicy( QWidget::StrongFocus );
+ // Did we start a new row?
+ if ( m_nextPosition.x == 1 )
+ updateGeometry();
+}
+
+bool KoColorPanel::insertColor( const QColor& color, bool checking )
+{
+ if ( checking && isAvailable( color ) )
+ return false;
+
+ m_colorMap.insert( m_nextPosition, color );
+
+ ++m_nextPosition.x;
+ if ( m_nextPosition.x == COLS ) {
+ m_nextPosition.x = 0;
+ ++m_nextPosition.y;
+ }
+ return true;
+}
+
+bool KoColorPanel::insertColor( const QColor& color, const QString& toolTip, bool checking )
+{
+ if ( checking && isAvailable( color ) )
+ return false;
+
+ // Remember the "old" m_nextPosition -- this is the place where the newly
+ // inserted color will be located
+ QRect rect( mapFromPosition( m_nextPosition ) );
+ insertColor( color, false ); // check only once ;)
+ QToolTip::add( this, rect, toolTip );
+ return true;
+}
+
+bool KoColorPanel::isAvailable( const QColor& color )
+{
+ // O(n) checking on insert, but this is better than O(n) checking
+ // on every mouse move...
+ QMap<Position, QColor>::ConstIterator it = m_colorMap.begin();
+ QMap<Position, QColor>::ConstIterator end = m_colorMap.end();
+ for ( ; it != end; ++it )
+ if ( it.data() == color )
+ return true;
+ return false;
+}
+
+KoColorPanel::Position KoColorPanel::mapToPosition( const QPoint& point ) const
+{
+ return Position( point.x() >> 4, point.y() >> 4 );
+}
+
+QColor KoColorPanel::mapToColor( const QPoint& point ) const
+{
+ return mapToColor( mapToPosition( point ) );
+}
+
+QColor KoColorPanel::mapToColor( const KoColorPanel::Position& position ) const
+{
+ QMap<Position, QColor>::ConstIterator it = m_colorMap.find( position );
+ if ( it != m_colorMap.end() )
+ return it.data();
+ return QColor();
+}
+
+QRect KoColorPanel::mapFromPosition( const KoColorPanel::Position& position ) const
+{
+ return QRect( position.x << 4, position.y << 4, TILESIZE, TILESIZE );
+}
+
+KoColorPanel::Position KoColorPanel::validPosition( const Position& position )
+{
+ Position pos( position );
+ int lns = lines() - 1;
+ int lastLineLen = m_colorMap.count() % COLS - 1;
+
+ // ensure the position is within the valid grid area
+ // note: special handling of the last line
+ if ( pos.x < 0 )
+ pos.x = 0;
+ else if ( pos.y == lns && pos.x > lastLineLen )
+ pos.x = lastLineLen;
+ else if ( pos.x >= COLS )
+ pos.x = COLS - 1;
+
+ if ( pos.y < 0 )
+ pos.y = 0;
+ else if ( pos.x > lastLineLen && pos.y > lns - 1 )
+ pos.y = lns - 1;
+ else if ( pos.y > lns )
+ pos.y = lns;
+ return pos;
+}
+
+int KoColorPanel::lines() const
+{
+ if ( m_colorMap.isEmpty() )
+ return 1;
+ return ( m_colorMap.count() - 1 ) / COLS + 1;
+}
+
+void KoColorPanel::paintArea( const QRect& rect, int& startRow, int& endRow, int& startCol, int& endCol ) const
+{
+ startRow = rect.top() >> 4;
+ endRow = ( rect.bottom() >> 4 ) + 1;
+ startCol = rect.left() >> 4;
+ endCol = ( rect.right() >> 4 ) + 1;
+}
+
+void KoColorPanel::updateFocusPosition( const Position& newPosition )
+{
+ QPainter p( this );
+
+ // restore the old tile where we had the focus before
+ if ( m_focusPosition.x != -1 && m_focusPosition.y != -1 )
+ paint( m_focusPosition );
+
+ m_focusPosition = newPosition;
+
+ QMap<Position, QColor>::ConstIterator it = m_colorMap.find( m_focusPosition );
+ if ( it != m_colorMap.end() ) {
+ // draw at the new focus position
+ style().drawPrimitive( QStyle::PE_Panel, &p, QRect( m_focusPosition.x << 4, m_focusPosition.y << 4, TILESIZE, TILESIZE ),
+ colorGroup(), QStyle::Style_Sunken | QStyle::Style_Enabled );
+ p.fillRect( ( m_focusPosition.x << 4 ) + 2, ( m_focusPosition.y << 4 ) + 2, 12, 12, it.data() );
+ }
+
+}
+
+void KoColorPanel::paint( const Position& position )
+{
+ QMap<Position, QColor>::ConstIterator it = m_colorMap.find( position );
+ if ( it == m_colorMap.end() )
+ return;
+
+ erase( mapFromPosition( position ) );
+ QPainter p( this );
+ p.fillRect( ( position.x << 4 ) + 2, ( position.y << 4 ) + 2, 12, 12, it.data() );
+}
+
+void KoColorPanel::init()
+{
+ setFocusPolicy( QWidget::NoFocus ); // it's empty
+ m_nextPosition.x = 0;
+ m_nextPosition.y = 0;
+ m_focusPosition.x = -1;
+ m_focusPosition.y = -1;
+ m_defaultsAdded = false;
+}
+
+bool operator<( const KoColorPanel::Position& lhs, const KoColorPanel::Position& rhs )
+{
+ return ( lhs.y * COLS + lhs.x ) < ( rhs.y * COLS + rhs.x );
+}
+
+
+KoColorPopupProxy::KoColorPopupProxy( const QColor& defaultColor, KoColorPanel* recentColors, QObject* parent, const char* name ) :
+ QObject( parent, name ), m_defaultColor( defaultColor ), m_recentColors( recentColors )
+{
+}
+
+void KoColorPopupProxy::setRecentColorPanel( KoColorPanel* recentColors )
+{
+ m_recentColors = recentColors;
+}
+
+void KoColorPopupProxy::slotDefaultColor()
+{
+ emit colorSelected( m_defaultColor );
+}
+
+void KoColorPopupProxy::slotMoreColors()
+{
+ if ( !m_recentColors )
+ return;
+
+ QColor newColor;
+ QWidget* p = 0;
+ if ( parent() && parent()->isWidgetType() )
+ p = static_cast<QWidget*>( parent() );
+
+ if ( KColorDialog::getColor( newColor, p ) == QDialog::Accepted ) {
+ m_recentColors->insertColor( newColor );
+ emit colorSelected( newColor );
+ }
+}
+
+
+KoToolButton::KoToolButton( const QString& icon, int id, QWidget* parent,
+ const char* name, const QString& txt, KInstance* _instance ) :
+ KToolBarButton( icon, id, parent, name, txt, _instance ), m_arrowPressed( false )
+{
+ init();
+}
+
+KoToolButton::KoToolButton( const QPixmap& pixmap, int id, QWidget* parent,
+ const char* name, const QString& txt ) :
+ KToolBarButton( pixmap, id, parent, name, txt ), m_arrowPressed( false )
+{
+ init();
+}
+
+KoToolButton::~KoToolButton()
+{
+}
+
+QSize KoToolButton::sizeHint() const
+{
+ return minimumSizeHint();
+}
+
+QSize KoToolButton::minimumSizeHint() const
+{
+ QSize size = KToolBarButton::minimumSizeHint();
+ size.setWidth( size.width() + ARROW_WIDTH );
+ return size;
+}
+
+QSize KoToolButton::minimumSize() const
+{
+ return minimumSizeHint();
+}
+
+void KoToolButton::colorSelected( const QColor& color )
+{
+ kdDebug() << "selected::: " << color.name() << endl;
+}
+
+void KoToolButton::drawButton(QPainter *_painter)
+{
+ QStyle::SFlags flags = QStyle::Style_Default;
+ QStyle::SCFlags active = QStyle::SC_None;
+ QStyle::SCFlags arrowActive = QStyle::SC_None;
+ QStyleOption opt;
+ QColorGroup cg( colorGroup() );
+
+ if ( isEnabled() ) {
+ flags |= QStyle::Style_Enabled;
+ if ( KToolBarButton::isRaised() || m_arrowPressed )
+ flags |= QStyle::Style_Raised;
+ }
+ if ( isOn() )
+ flags |= QStyle::Style_On;
+
+ QStyle::SFlags arrowFlags = flags;
+
+ if ( isDown() && !m_arrowPressed ) {
+ flags |= QStyle::Style_Down;
+ active |= QStyle::SC_ToolButton;
+ }
+ if ( m_arrowPressed )
+ arrowActive |= QStyle::SC_ToolButton;
+
+ // Draw styled toolbuttons
+ _painter->setClipRect( 0, 0, width() - ARROW_WIDTH, height() );
+ style().drawComplexControl( QStyle::CC_ToolButton, _painter, this, QRect( 0, 0, width() - ARROW_WIDTH, height() ), cg,
+ flags, QStyle::SC_ToolButton, active, opt );
+ _painter->setClipRect( width() - ARROW_WIDTH, 0, ARROW_WIDTH, height() );
+ style().drawComplexControl( QStyle::CC_ToolButton, _painter, this, QRect( width(), 0, ARROW_WIDTH, height() ), cg,
+ arrowFlags, QStyle::SC_ToolButton, arrowActive, opt );
+ _painter->setClipping( false );
+
+ // ...and the arrow indicating the popup
+ style().drawPrimitive( QStyle::PE_ArrowDown, _painter, QRect( width() - ARROW_WIDTH - 1, 0, ARROW_WIDTH, height() ),
+ cg, flags, opt );
+
+ if ( KToolBarButton::isRaised() || m_arrowPressed )
+ qDrawShadeLine( _painter, width() - ARROW_WIDTH - 1, 0, width() - ARROW_WIDTH - 1, height() - 1, colorGroup(), true );
+
+ int dx, dy;
+ QFont tmp_font( KGlobalSettings::toolBarFont() );
+ QFontMetrics fm( tmp_font );
+ QRect textRect;
+ int textFlags = 0;
+
+ if ( static_cast<KToolBar::IconText>( iconTextMode() ) == KToolBar::IconOnly ) { // icon only
+ QPixmap pixmap = iconSet().pixmap( QIconSet::Automatic,
+ isEnabled() ? ( KToolBarButton::isActive() ? QIconSet::Active : QIconSet::Normal ) :
+ QIconSet::Disabled, isOn() ? QIconSet::On : QIconSet::Off );
+ if ( !pixmap.isNull() ) {
+ dx = ( width() - ARROW_WIDTH - pixmap.width() ) / 2;
+ dy = ( height() - pixmap.height() ) / 2;
+ buttonShift( dx, dy );
+ _painter->drawPixmap( dx, dy, pixmap );
+ }
+ }
+ else if ( static_cast<KToolBar::IconText>( iconTextMode() ) == KToolBar::IconTextRight ) { // icon and text (if any)
+ QPixmap pixmap = iconSet().pixmap( QIconSet::Automatic,
+ isEnabled() ? ( KToolBarButton::isActive() ? QIconSet::Active : QIconSet::Normal ) :
+ QIconSet::Disabled, isOn() ? QIconSet::On : QIconSet::Off );
+ if( !pixmap.isNull()) {
+ dx = 4;
+ dy = ( height() - pixmap.height() ) / 2;
+ buttonShift( dx, dy );
+ _painter->drawPixmap( dx, dy, pixmap );
+ }
+
+ if (!textLabel().isNull()) {
+ textFlags = AlignVCenter | AlignLeft;
+ if ( !pixmap.isNull() )
+ dx = 4 + pixmap.width() + 2;
+ else
+ dx = 4;
+ dy = 0;
+ buttonShift( dx, dy );
+ textRect = QRect( dx, dy, width() - dx, height() );
+ }
+ }
+ else if ( static_cast<KToolBar::IconText>( iconTextMode() ) == KToolBar::TextOnly ) {
+ if ( !textLabel().isNull() ) {
+ textFlags = AlignTop | AlignLeft;
+ dx = ( width() - ARROW_WIDTH - fm.width( textLabel() ) ) / 2;
+ dy = ( height() - fm.lineSpacing() ) / 2;
+ buttonShift( dx, dy );
+ textRect = QRect( dx, dy, fm.width(textLabel()), fm.lineSpacing() );
+ }
+ }
+ else if ( static_cast<KToolBar::IconText>( iconTextMode() ) == KToolBar::IconTextBottom ) {
+ QPixmap pixmap = iconSet().pixmap( QIconSet::Automatic,
+ isEnabled() ? ( KToolBarButton::isActive() ? QIconSet::Active : QIconSet::Normal ) :
+ QIconSet::Disabled, isOn() ? QIconSet::On : QIconSet::Off );
+ if( !pixmap.isNull()) {
+ dx = ( width() - ARROW_WIDTH - pixmap.width() ) / 2;
+ dy = ( height() - fm.lineSpacing() - pixmap.height() ) / 2;
+ buttonShift( dx, dy );
+ _painter->drawPixmap( dx, dy, pixmap );
+ }
+
+ if ( !textLabel().isNull() ) {
+ textFlags = AlignBottom | AlignHCenter;
+ dx = ( width() - ARROW_WIDTH - fm.width( textLabel() ) ) / 2;
+ dy = height() - fm.lineSpacing() - 4;
+ buttonShift( dx, dy );
+ textRect = QRect( dx, dy, fm.width( textLabel() ), fm.lineSpacing() );
+ }
+ }
+
+ // Draw the text at the position given by textRect, and using textFlags
+ if (!textLabel().isNull() && !textRect.isNull()) {
+ _painter->setFont( KGlobalSettings::toolBarFont() );
+ if ( !isEnabled() )
+ _painter->setPen( palette().disabled().dark() );
+ else if( KToolBarButton::isRaised() )
+ _painter->setPen( KGlobalSettings::toolBarHighlightColor() );
+ else
+ _painter->setPen( colorGroup().buttonText() );
+ _painter->drawText( textRect, textFlags, textLabel() );
+ }
+}
+
+bool KoToolButton::eventFilter( QObject* o, QEvent* e )
+{
+ if ( o == m_popup ) {
+ if ( e->type() == QEvent::MouseButtonPress )
+ if ( hitArrow( mapFromGlobal( static_cast<QMouseEvent*>( e )->globalPos() ) ) ) {
+ kdDebug() << "KoToolButton::eventFilter-------------->" << endl;
+ m_popup->close();
+ m_arrowPressed = false;
+ return true;
+ }
+ return false;
+ }
+
+ if ( e->type() == QEvent::MouseButtonPress ) {
+ m_arrowPressed = hitArrow( static_cast<QMouseEvent*>( e )->pos() );
+ if ( m_arrowPressed )
+ m_popup->popup( mapToGlobal( QPoint( 0, height() ) ) );
+ }
+ else if ( e->type() == QEvent::MouseButtonRelease )
+ m_arrowPressed = false;
+ return KToolBarButton::eventFilter( o, e );
+}
+
+void KoToolButton::init()
+{
+ m_popup = KoColorPanel::createColorPopup( KoColorPanel::CustomColors, Qt::yellow, this,
+ SLOT( colorSelected( const QColor& ) ),
+ this, "no-name" );
+ // We are interested in the mouse clicks on the arrow button
+ m_popup->installEventFilter( this );
+
+ ARROW_WIDTH = style().pixelMetric(QStyle::PM_MenuButtonIndicator) + 4;
+ kdDebug() << "##################### Arrow: " << ARROW_WIDTH << endl;
+}
+
+void KoToolButton::buttonShift( int& dx, int& dy )
+{
+ if ( isDown() && !m_arrowPressed ) {
+ dx += style().pixelMetric( QStyle::PM_ButtonShiftHorizontal );
+ dy += style().pixelMetric( QStyle::PM_ButtonShiftVertical );
+ }
+}
+
+bool KoToolButton::hitArrow( const QPoint& pos )
+{
+ return QRect( width() - ARROW_WIDTH, 0, ARROW_WIDTH, height() ).contains( pos );
+}
+
+#include <KoTooluButton.moc>
diff --git a/lib/kofficeui/KoTooluButton.h b/lib/kofficeui/KoTooluButton.h
new file mode 100644
index 00000000..b933eeee
--- /dev/null
+++ b/lib/kofficeui/KoTooluButton.h
@@ -0,0 +1,183 @@
+/* This file is part of the KDE project
+ Copyright (C) 2002 Werner Trobin <trobin@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#ifndef _kotoolbutton_h_
+#define _kotoolbutton_h_
+
+#include <ktoolbarbutton.h>
+#include <qmap.h>
+#include <qpoint.h>
+
+class QPopupMenu;
+
+class KoColorPanel : public QWidget
+{
+ Q_OBJECT
+public:
+ KoColorPanel( QWidget* parent = 0, const char* name = 0 );
+ virtual ~KoColorPanel();
+
+ virtual QSize sizeHint() const;
+ virtual QSize minimumSizeHint() const;
+
+ enum MenuStyle { Plain, CustomColors };
+ static QPopupMenu* createColorPopup( MenuStyle style, const QColor& defaultColor,
+ const QObject* receiver, const char* slot,
+ QWidget* parent, const char* name );
+
+public slots:
+ void clear();
+ void insertColor( const QColor& color );
+ void insertColor( const QColor& color, const QString& toolTip );
+ void insertDefaultColors();
+
+signals:
+ void colorSelected( const QColor& color );
+
+protected:
+ virtual void mousePressEvent( QMouseEvent* e );
+ virtual void mouseReleaseEvent( QMouseEvent* e );
+ virtual void mouseMoveEvent( QMouseEvent* e );
+ virtual void paintEvent( QPaintEvent* e );
+ virtual void keyPressEvent( QKeyEvent* e );
+ virtual void focusInEvent( QFocusEvent* e );
+ virtual void dragEnterEvent( QDragEnterEvent* e );
+ virtual void dropEvent( QDropEvent* e );
+
+private:
+ // The position of the 16x16 tiles in "tile steps"
+ struct Position {
+ Position() : x( -1 ), y( -1 ) {}
+ Position( short x_, short y_ ) : x( x_ ), y( y_ ) {}
+
+ short x;
+ short y;
+ };
+ friend bool operator<( const KoColorPanel::Position& lhs, const KoColorPanel::Position& rhs );
+
+ void finalizeInsertion( const Position& pos );
+ bool insertColor( const QColor& color, bool checking );
+ bool insertColor( const QColor& color, const QString& toolTip, bool checking );
+ bool isAvailable( const QColor& color );
+
+ Position mapToPosition( const QPoint& point ) const;
+ QColor mapToColor( const QPoint& point ) const;
+ QColor mapToColor( const Position& position ) const;
+ QRect mapFromPosition( const Position& position ) const;
+ Position validPosition( const Position& position );
+
+ int lines() const;
+ void paintArea( const QRect& rect, int& startRow, int& endRow, int& startCol, int& endCol ) const;
+ void updateFocusPosition( const Position& newPosition );
+ void paint( const Position& position );
+ void init();
+
+ Position m_nextPosition, m_focusPosition;
+ QMap<Position, QColor> m_colorMap;
+ QPoint m_pressedPos;
+ bool m_defaultsAdded;
+};
+
+// Needed for the use of KoColorPanel::Position in QMap
+bool operator<( const KoColorPanel::Position& lhs, const KoColorPanel::Position& rhs );
+
+
+// A tiny class needed to emit the correct signal when the default
+// color item in the color-panel popup is activated. Additionally
+// it's used to provide the color select dialog and manages the recent
+// colors... hacky
+class KoColorPopupProxy : public QObject
+{
+ Q_OBJECT
+public:
+ KoColorPopupProxy( const QColor& defaultColor, KoColorPanel* recentColors, QObject* parent, const char* name );
+ virtual ~KoColorPopupProxy() {}
+
+ void setRecentColorPanel( KoColorPanel* recentColors );
+
+public slots:
+ void slotDefaultColor();
+ void slotMoreColors();
+
+signals:
+ void colorSelected( const QColor& color );
+
+private:
+ QColor m_defaultColor;
+ KoColorPanel* m_recentColors;
+};
+
+
+// Parts of the code are from KToolBarButton
+class KoToolButton : public KToolBarButton
+{
+ Q_OBJECT
+public:
+ /**
+ * Construct a button with an icon loaded by the button itself.
+ * This will trust the button to load the correct icon with the
+ * correct size.
+ *
+ * @param icon Name of icon to load (may be absolute or relative)
+ * @param id Id of this button
+ * @param parent This button's parent
+ * @param name This button's internal name
+ * @param txt This button's text (in a tooltip or otherwise)
+ */
+ KoToolButton( const QString& icon, int id, QWidget* parent,
+ const char* name = 0L, const QString& txt = QString::null,
+ KInstance* _instance = KGlobal::instance() );
+
+ /**
+ * Construct a button with an existing pixmap. It is not
+ * recommended that you use this as the internal icon loading code
+ * will almost always get it "right".
+ *
+ * @param icon Name of icon to load (may be absolute or relative)
+ * @param id Id of this button
+ * @param parent This button's parent
+ * @param name This button's internal name
+ * @param txt This button's text (in a tooltip or otherwise)
+ */
+ KoToolButton( const QPixmap& pixmap, int id, QWidget* parent,
+ const char* name = 0L, const QString& txt = QString::null );
+
+ virtual ~KoToolButton();
+
+ virtual QSize sizeHint() const;
+ virtual QSize minimumSizeHint() const;
+ virtual QSize minimumSize() const;
+
+public slots:
+ void colorSelected( const QColor& color );
+
+protected:
+ virtual void drawButton(QPainter *p);
+ virtual bool eventFilter( QObject* o, QEvent* e );
+
+private:
+ void init();
+ void buttonShift( int& dx, int& dy );
+ bool hitArrow( const QPoint& pos );
+
+ QPopupMenu* m_popup;
+ bool m_arrowPressed;
+};
+
+#endif // _kotoolbutton_h_
diff --git a/lib/kofficeui/KoUnitWidgets.cpp b/lib/kofficeui/KoUnitWidgets.cpp
new file mode 100644
index 00000000..00899882
--- /dev/null
+++ b/lib/kofficeui/KoUnitWidgets.cpp
@@ -0,0 +1,455 @@
+/* This file is part of the KDE project
+ Copyright (C) 2002, Rob Buis(buis@kde.org)
+ Copyright (C) 2004, Nicolas GOUTTE <goutte@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#include "KoUnitWidgets.h"
+#include "KoUnitWidgets.moc"
+#include <kdebug.h>
+#include <kglobal.h>
+#include <klocale.h>
+#include <qpushbutton.h>
+#include <qlayout.h>
+
+
+// ----------------------------------------------------------------
+// Support classes
+
+
+KoUnitDoubleValidator::KoUnitDoubleValidator( KoUnitDoubleBase *base, QObject *parent, const char *name )
+: KDoubleValidator( parent, name ), m_base( base )
+{
+}
+
+QValidator::State
+KoUnitDoubleValidator::validate( QString &s, int &pos ) const
+{
+
+ kdDebug(30004) << "KoUnitDoubleValidator::validate : " << s << " at " << pos << endl;
+ QValidator::State result = Acceptable;
+
+ QRegExp regexp ("([ a-zA-Z]+)$"); // Letters or spaces at end
+ const int res = regexp.search( s );
+
+ if ( res == -1 )
+ {
+ // Nothing like an unit? The user is probably editing the unit
+ kdDebug(30004) << "Intermediate (no unit)" << endl;
+ return Intermediate;
+ }
+
+ // ### TODO: are all the QString::stripWhiteSpace really necessary?
+ const QString number ( s.left( res ).stripWhiteSpace() );
+ const QString unitName ( regexp.cap( 1 ).stripWhiteSpace().lower() );
+
+ kdDebug(30004) << "Split:" << number << ":" << unitName << ":" << endl;
+
+ bool ok = false;
+ const double value = m_base->toDouble( number, &ok );
+ double newVal = 0.0;
+ if( ok )
+ {
+ KoUnit::Unit unit = KoUnit::unit( unitName, &ok );
+ if ( ok )
+ newVal = KoUnit::fromUserValue( value, unit );
+ else
+ {
+ // Probably the user is trying to edit the unit
+ kdDebug(30004) << "Intermediate (unknown unit)" << endl;
+ return Intermediate;
+ }
+ }
+ else
+ {
+ kdWarning(30004) << "Not a number: " << number << endl;
+ return Invalid;
+ }
+
+ newVal = KoUnit::ptToUnit( newVal, m_base->m_unit );
+
+ s = m_base->getVisibleText( newVal );
+
+ return result;
+}
+
+
+QString KoUnitDoubleBase::getVisibleText( double value ) const
+{
+ const QString num ( QString( "%1%2").arg( KGlobal::locale()->formatNumber( value, m_precision ), KoUnit::unitName( m_unit ) ) );
+ kdDebug(30004) << "getVisibleText: " << QString::number( value, 'f', 12 ) << " => " << num << endl;
+ return num;
+}
+
+double KoUnitDoubleBase::toDouble( const QString& str, bool* ok ) const
+{
+ QString str2( str );
+ /* KLocale::readNumber wants the thousand separator exactly at 1000.
+ But when editing, it might be anywhere. So we need to remove it. */
+ const QString sep( KGlobal::locale()->thousandsSeparator() );
+ if ( !sep.isEmpty() )
+ str2.remove( sep );
+ str2.remove( KoUnit::unitName( m_unit ) );
+ const double dbl = KGlobal::locale()->readNumber( str2, ok );
+ if ( ok )
+ kdDebug(30004) << "toDouble:" << str << ": => :" << str2 << ": => " << QString::number( dbl, 'f', 12 ) << endl;
+ else
+ kdWarning(30004) << "toDouble error:" << str << ": => :" << str2 << ":" << endl;
+ return dbl;
+}
+
+
+// ----------------------------------------------------------------
+// Widget classes
+
+
+KoUnitDoubleSpinBox::KoUnitDoubleSpinBox( QWidget *parent, const char *name )
+ : KDoubleSpinBox( parent, name ), KoUnitDoubleBase( KoUnit::U_PT, 2 )
+ , m_lowerInPoints( -9999 )
+ , m_upperInPoints( 9999 )
+ , m_stepInPoints( 1 )
+{
+ KDoubleSpinBox::setPrecision( 2 );
+ m_validator = new KoUnitDoubleValidator( this, this );
+ QSpinBox::setValidator( m_validator );
+ setAcceptLocalizedNumbers( true );
+ setUnit( KoUnit::U_PT );
+
+ connect(this, SIGNAL(valueChanged( double )), SLOT(privateValueChanged()));
+}
+
+
+KoUnitDoubleSpinBox::KoUnitDoubleSpinBox( QWidget *parent,
+ double lower, double upper,
+ double step,
+ double value,
+ KoUnit::Unit unit,
+ unsigned int precision,
+ const char *name )
+ : KDoubleSpinBox( lower, upper, step, value, precision, parent, name ),
+ KoUnitDoubleBase( unit, precision ),
+ m_lowerInPoints( lower ), m_upperInPoints( upper ), m_stepInPoints( step )
+{
+ m_unit = KoUnit::U_PT;
+ m_validator = new KoUnitDoubleValidator( this, this );
+ QSpinBox::setValidator( m_validator );
+ setAcceptLocalizedNumbers( true );
+ setUnit( unit );
+ changeValue( value );
+ setLineStep( 0.5 );
+
+ connect(this, SIGNAL(valueChanged( double )), SLOT(privateValueChanged()));
+}
+
+void
+KoUnitDoubleSpinBox::changeValue( double val )
+{
+ KDoubleSpinBox::setValue( KoUnit::toUserValue( val, m_unit ) );
+ // TODO: emit valueChanged ONLY if the value was out-of-bounds
+ // This will allow the 'user' dialog to set a dirty bool and ensure
+ // a proper value is getting saved.
+}
+
+void KoUnitDoubleSpinBox::privateValueChanged() {
+ emit valueChangedPt( value () );
+}
+
+void
+KoUnitDoubleSpinBox::setUnit( KoUnit::Unit unit )
+{
+ double oldvalue = KoUnit::fromUserValue( KDoubleSpinBox::value(), m_unit );
+ KDoubleSpinBox::setMinValue( KoUnit::toUserValue( m_lowerInPoints, unit ) );
+ KDoubleSpinBox::setMaxValue( KoUnit::toUserValue( m_upperInPoints, unit ) );
+ KDoubleSpinBox::setLineStep( KoUnit::toUserValue( m_stepInPoints, unit ) );
+ KDoubleSpinBox::setValue( KoUnit::ptToUnit( oldvalue, unit ) );
+ m_unit = unit;
+ setSuffix( KoUnit::unitName( unit ).prepend( ' ' ) );
+}
+
+double KoUnitDoubleSpinBox::value( void ) const
+{
+ return KoUnit::fromUserValue( KDoubleSpinBox::value(), m_unit );
+}
+
+void KoUnitDoubleSpinBox::setMinValue( double min )
+{
+ m_lowerInPoints = min;
+ KDoubleSpinBox::setMinValue( KoUnit::toUserValue( m_lowerInPoints, m_unit ) );
+}
+
+void KoUnitDoubleSpinBox::setMaxValue( double max )
+{
+ m_upperInPoints = max;
+ KDoubleSpinBox::setMaxValue( KoUnit::toUserValue( m_upperInPoints, m_unit ) );
+}
+
+void KoUnitDoubleSpinBox::setLineStep( double step )
+{
+ m_stepInPoints = KoUnit::toUserValue(step, KoUnit::U_PT );
+ KDoubleSpinBox::setLineStep( step );
+}
+
+void KoUnitDoubleSpinBox::setLineStepPt( double step )
+{
+ m_stepInPoints = step;
+ KDoubleSpinBox::setLineStep( KoUnit::toUserValue( m_stepInPoints, m_unit ) );
+}
+
+void KoUnitDoubleSpinBox::setMinMaxStep( double min, double max, double step )
+{
+ setMinValue( min );
+ setMaxValue( max );
+ setLineStepPt( step );
+}
+
+// ----------------------------------------------------------------
+
+
+KoUnitDoubleLineEdit::KoUnitDoubleLineEdit( QWidget *parent, const char *name )
+ : KLineEdit( parent, name ), KoUnitDoubleBase( KoUnit::U_PT, 2 ), m_value( 0.0 ), m_lower( 0.0 ), m_upper( 9999.99 ),
+ m_lowerInPoints( 0.0 ), m_upperInPoints( 9999.99 )
+{
+ setAlignment( Qt::AlignRight );
+ m_validator = new KoUnitDoubleValidator( this, this );
+ setValidator( m_validator );
+ setUnit( KoUnit::U_PT );
+ changeValue( KoUnit::ptToUnit( 0.0, KoUnit::U_PT ) );
+}
+
+KoUnitDoubleLineEdit::KoUnitDoubleLineEdit( QWidget *parent, double lower, double upper, double value, KoUnit::Unit unit,
+ unsigned int precision, const char *name )
+ : KLineEdit( parent, name ), KoUnitDoubleBase( unit, precision ), m_value( value ), m_lower( lower ), m_upper( upper ),
+ m_lowerInPoints( lower ), m_upperInPoints( upper )
+{
+ setAlignment( Qt::AlignRight );
+ m_validator = new KoUnitDoubleValidator( this, this );
+ setValidator( m_validator );
+ setUnit( unit );
+ changeValue( KoUnit::ptToUnit( value, unit ) );
+}
+
+void
+KoUnitDoubleLineEdit::changeValue( double value )
+{
+ m_value = value < m_lower ? m_lower : ( value > m_upper ? m_upper : value );
+ setText( getVisibleText( m_value ) );
+}
+
+void
+KoUnitDoubleLineEdit::setUnit( KoUnit::Unit unit )
+{
+ KoUnit::Unit old = m_unit;
+ m_unit = unit;
+ m_lower = KoUnit::ptToUnit( m_lowerInPoints, unit );
+ m_upper = KoUnit::ptToUnit( m_upperInPoints, unit );
+ changeValue( KoUnit::ptToUnit( KoUnit::fromUserValue( m_value, old ), unit ) );
+}
+
+bool
+KoUnitDoubleLineEdit::eventFilter( QObject* o, QEvent* ev )
+{
+#if 0
+ if( ev->type() == QEvent::FocusOut || ev->type() == QEvent::Leave || ev->type() == QEvent::Hide )
+ {
+ bool ok;
+ double value = toDouble( text(), &ok );
+ changeValue( value );
+ return false;
+ }
+ else
+#endif
+ return QLineEdit::eventFilter( o, ev );
+}
+
+double KoUnitDoubleLineEdit::value( void ) const
+{
+ return KoUnit::fromUserValue( m_value, m_unit );
+}
+
+
+// ----------------------------------------------------------------
+
+
+KoUnitDoubleComboBox::KoUnitDoubleComboBox( QWidget *parent, const char *name )
+ : KComboBox( true, parent, name ), KoUnitDoubleBase( KoUnit::U_PT, 2 ), m_value( 0.0 ), m_lower( 0.0 ), m_upper( 9999.99 ), m_lowerInPoints( 0.0 ), m_upperInPoints( 9999.99 )
+{
+ lineEdit()->setAlignment( Qt::AlignRight );
+ m_validator = new KoUnitDoubleValidator( this, this );
+ lineEdit()->setValidator( m_validator );
+ setUnit( KoUnit::U_PT );
+ changeValue( KoUnit::ptToUnit( 0.0, KoUnit::U_PT ) );
+ connect( this, SIGNAL( activated( int ) ), this, SLOT( slotActivated( int ) ) );
+}
+
+KoUnitDoubleComboBox::KoUnitDoubleComboBox( QWidget *parent, double lower, double upper, double value, KoUnit::Unit unit,
+ unsigned int precision, const char *name )
+ : KComboBox( true, parent, name ), KoUnitDoubleBase( unit, precision ), m_value( value ), m_lower( lower ), m_upper( upper ),
+ m_lowerInPoints( lower ), m_upperInPoints( upper )
+{
+ lineEdit()->setAlignment( Qt::AlignRight );
+ m_validator = new KoUnitDoubleValidator( this, this );
+ lineEdit()->setValidator( m_validator );
+ setUnit( unit );
+ changeValue( KoUnit::ptToUnit( value, unit ) );
+ connect( this, SIGNAL( activated( int ) ), this, SLOT( slotActivated( int ) ) );
+}
+
+void
+KoUnitDoubleComboBox::changeValue( double value )
+{
+ QString oldLabel = lineEdit()->text();
+ updateValue( value );
+ if( lineEdit()->text() != oldLabel )
+ emit valueChanged( m_value );
+}
+
+void
+KoUnitDoubleComboBox::updateValue( double value )
+{
+ m_value = value < m_lower ? m_lower : ( value > m_upper ? m_upper : value );
+ lineEdit()->setText( getVisibleText( m_value ) );
+}
+
+void
+KoUnitDoubleComboBox::insertItem( double value, int index )
+{
+ KComboBox::insertItem( getVisibleText( value ), index );
+}
+
+void
+KoUnitDoubleComboBox::slotActivated( int index )
+{
+ double oldvalue = m_value;
+ bool ok;
+ double value = toDouble( text( index ), &ok );
+ m_value = value < m_lower ? m_lower : ( value > m_upper ? m_upper : value );
+ if( m_value != oldvalue )
+ emit valueChanged( m_value );
+}
+
+void
+KoUnitDoubleComboBox::setUnit( KoUnit::Unit unit )
+{
+ KoUnit::Unit old = m_unit;
+ m_unit = unit;
+ m_lower = KoUnit::ptToUnit( m_lowerInPoints, unit );
+ m_upper = KoUnit::ptToUnit( m_upperInPoints, unit );
+ changeValue( KoUnit::ptToUnit( KoUnit::fromUserValue( m_value, old ), unit ) );
+}
+
+bool
+KoUnitDoubleComboBox::eventFilter( QObject* o, QEvent* ev )
+{
+#if 0
+ if( ev->type() == QEvent::FocusOut || ev->type() == QEvent::Leave || ev->type() == QEvent::Hide )
+ {
+ bool ok;
+ double value = toDouble( lineEdit()->text(), &ok );
+ changeValue( value );
+ return false;
+ }
+ else
+#endif
+ return QComboBox::eventFilter( o, ev );
+}
+
+double KoUnitDoubleComboBox::value( void ) const
+{
+ return KoUnit::fromUserValue( m_value, m_unit );
+}
+
+
+// ----------------------------------------------------------------
+
+
+KoUnitDoubleSpinComboBox::KoUnitDoubleSpinComboBox( QWidget *parent, const char *name )
+ : QWidget( parent ), m_step( 1.0 )
+{
+ QGridLayout *layout = new QGridLayout( this, 2, 3 );
+ //layout->setMargin( 2 );
+ QPushButton *up = new QPushButton( "+", this );
+ //up->setFlat( true );
+ up->setMaximumHeight( 15 );
+ up->setMaximumWidth( 15 );
+ layout->addWidget( up, 0, 0 );
+ connect( up, SIGNAL( clicked() ), this, SLOT( slotUpClicked() ) );
+
+ QPushButton *down = new QPushButton( "-", this );
+ down->setMaximumHeight( 15 );
+ down->setMaximumWidth( 15 );
+ layout->addWidget( down, 1, 0 );
+ connect( down, SIGNAL( clicked() ), this, SLOT( slotDownClicked() ) );
+
+ m_combo = new KoUnitDoubleComboBox( this, KoUnit::ptToUnit( 0.0, KoUnit::U_PT ), KoUnit::ptToUnit( 9999.99, KoUnit::U_PT ), 0.0, KoUnit::U_PT, 2, name );
+ connect( m_combo, SIGNAL( valueChanged( double ) ), this, SIGNAL( valueChanged( double ) ) );
+ layout->addMultiCellWidget( m_combo, 0, 1, 2, 2 );
+}
+
+KoUnitDoubleSpinComboBox::KoUnitDoubleSpinComboBox( QWidget *parent, double lower, double upper, double step, double value,
+ KoUnit::Unit unit, unsigned int precision, const char *name )
+ : QWidget( parent ), m_step( step )//, m_lowerInPoints( lower ), m_upperInPoints( upper )
+{
+ QGridLayout *layout = new QGridLayout( this, 2, 3 );
+ //layout->setMargin( 2 );
+ QPushButton *up = new QPushButton( "+", this );
+ //up->setFlat( true );
+ up->setMaximumHeight( 15 );
+ up->setMaximumWidth( 15 );
+ layout->addWidget( up, 0, 0 );
+ connect( up, SIGNAL( clicked() ), this, SLOT( slotUpClicked() ) );
+
+ QPushButton *down = new QPushButton( "-", this );
+ down->setMaximumHeight( 15 );
+ down->setMaximumWidth( 15 );
+ layout->addWidget( down, 1, 0 );
+ connect( down, SIGNAL( clicked() ), this, SLOT( slotDownClicked() ) );
+
+ m_combo = new KoUnitDoubleComboBox( this, KoUnit::ptToUnit( lower, unit ), KoUnit::ptToUnit( upper, unit ), value, unit, precision, name );
+ connect( m_combo, SIGNAL( valueChanged( double ) ), this, SIGNAL( valueChanged( double ) ) );
+ layout->addMultiCellWidget( m_combo, 0, 1, 2, 2 );
+}
+
+void
+KoUnitDoubleSpinComboBox::slotUpClicked()
+{
+ m_combo->changeValue( m_combo->value() + m_step );
+}
+
+void
+KoUnitDoubleSpinComboBox::slotDownClicked()
+{
+ m_combo->changeValue( m_combo->value() - m_step );
+}
+
+void
+KoUnitDoubleSpinComboBox::insertItem( double value, int index )
+{
+ m_combo->insertItem( value, index );
+}
+
+void
+KoUnitDoubleSpinComboBox::updateValue( double value )
+{
+ m_combo->updateValue( value );
+}
+
+double
+KoUnitDoubleSpinComboBox::value() const
+{
+ return m_combo->value();
+}
+
diff --git a/lib/kofficeui/KoUnitWidgets.h b/lib/kofficeui/KoUnitWidgets.h
new file mode 100644
index 00000000..957b1b36
--- /dev/null
+++ b/lib/kofficeui/KoUnitWidgets.h
@@ -0,0 +1,246 @@
+/* This file is part of the KDE project
+ Copyright (C) 2002, Rob Buis(buis@kde.org)
+ Copyright (C) 2004, Nicolas GOUTTE <goutte@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#ifndef __KOUNITWIDGETS_H__
+#define __KOUNITWIDGETS_H__
+
+#include <knuminput.h>
+#include <knumvalidator.h>
+#include <klineedit.h>
+#include <kcombobox.h>
+#include <KoUnit.h>
+#include <koffice_export.h>
+
+
+// ----------------------------------------------------------------
+// Support classes
+
+
+class KoUnitDoubleBase;
+
+// ### TODO: put it out of the public header file (if possible)
+/**
+ * Validator for the unit widget classes
+ * \internal
+ * \since 1.4 (change of behavior)
+ */
+class KOFFICEUI_EXPORT KoUnitDoubleValidator : public KDoubleValidator
+{
+public:
+ KoUnitDoubleValidator( KoUnitDoubleBase *base, QObject *parent, const char *name = 0 );
+
+ virtual QValidator::State validate( QString &, int & ) const;
+
+private:
+ KoUnitDoubleBase *m_base;
+};
+
+
+/**
+ * Base for the unit widgets
+ * \since 1.4 (change of behavior)
+ */
+class KOFFICEUI_EXPORT KoUnitDoubleBase
+{
+public:
+ KoUnitDoubleBase( KoUnit::Unit unit, unsigned int precision ) : m_unit( unit ), m_precision( precision ) {}
+ virtual ~KoUnitDoubleBase() {}
+
+ virtual void changeValue( double ) = 0;
+ virtual void setUnit( KoUnit::Unit = KoUnit::U_PT ) = 0;
+
+ void setValueInUnit( double value, KoUnit::Unit unit )
+ {
+ changeValue( KoUnit::ptToUnit( KoUnit::fromUserValue( value, unit ), m_unit ) );
+ }
+
+ void setPrecision( unsigned int precision ) { m_precision = precision; };
+
+protected:
+ friend class KoUnitDoubleValidator;
+ /**
+ * Transform the double in a nice text, using locale symbols
+ * @param value the number as double
+ * @return the resulting string
+ */
+ QString getVisibleText( double value ) const;
+ /**
+ * Transfrom a string into a double, while taking care of locale specific symbols.
+ * @param str the string to transform into a number
+ * @param ok true, if the conversion was succesful
+ * @return the value as double
+ */
+ double toDouble( const QString& str, bool* ok ) const;
+
+protected:
+ KoUnitDoubleValidator *m_validator;
+ KoUnit::Unit m_unit;
+ unsigned int m_precision;
+};
+
+
+// ----------------------------------------------------------------
+// Widget classes
+
+
+/**
+ * Spin box for double precision numbers with unit display
+ * \since 1.4 (change of behavior)
+ */
+class KOFFICEUI_EXPORT KoUnitDoubleSpinBox : public KDoubleSpinBox, public KoUnitDoubleBase
+{
+ Q_OBJECT
+public:
+ KoUnitDoubleSpinBox( QWidget *parent = 0L, const char *name = 0L );
+ // lower, upper, step and value are in pt
+ KoUnitDoubleSpinBox( QWidget *parent, double lower, double upper, double step, double value = 0.0,
+ KoUnit::Unit unit = KoUnit::U_PT, unsigned int precision = 2, const char *name = 0 );
+ // added so the class can be used in .ui files(by Tymoteusz Majewski, maju7@o2.pl)
+ virtual void changeValue( double );
+ virtual void setUnit( KoUnit::Unit = KoUnit::U_PT );
+
+ /// @return the current value, converted in points
+ double value( void ) const;
+
+ /// Set minimum value in points.
+ void setMinValue(double min);
+
+ /// Set maximum value in points.
+ void setMaxValue(double max);
+
+ /// Set step size in the current unit.
+ void setLineStep(double step);
+
+ /// Set step size in points.
+ void setLineStepPt(double step);
+
+ /// Set minimum, maximum value and the step size (all in points) (by Tymoteusz Majewski, maju7@o2.pl)
+ void setMinMaxStep( double min, double max, double step );
+
+signals:
+ /// emitted like valueChanged in the parent, but this one emits the point value
+ void valueChangedPt( double );
+
+
+private:
+ double m_lowerInPoints; ///< lowest value in points
+ double m_upperInPoints; ///< highest value in points
+ double m_stepInPoints; ///< step in points
+
+private slots:
+ // exists to do emits for valueChangedPt
+ void privateValueChanged();
+};
+
+
+/**
+ * Line edit for double precision numbers with unit display
+ * \since 1.4 (change of behavior)
+ */
+class KOFFICEUI_EXPORT KoUnitDoubleLineEdit : public KLineEdit, public KoUnitDoubleBase
+{
+ Q_OBJECT
+public:
+ KoUnitDoubleLineEdit( QWidget *parent = 0L, const char *name = 0L );
+ KoUnitDoubleLineEdit( QWidget *parent, double lower, double upper, double value = 0.0, KoUnit::Unit unit = KoUnit::U_PT, unsigned int precision = 2, const char *name = 0 );
+
+ virtual void changeValue( double );
+ virtual void setUnit( KoUnit::Unit = KoUnit::U_PT );
+
+ /// @return the current value, converted in points
+ double value( void ) const;
+
+protected:
+ bool eventFilter( QObject* obj, QEvent* ev );
+
+private:
+ double m_value;
+ double m_lower;
+ double m_upper;
+ double m_lowerInPoints; ///< lowest value in points
+ double m_upperInPoints; ///< highest value in points
+};
+
+/**
+ * Combo box for double precision numbers with unit display
+ * \since 1.4 (change of behavior)
+ */
+class KOFFICEUI_EXPORT KoUnitDoubleComboBox : public KComboBox, public KoUnitDoubleBase
+{
+ Q_OBJECT
+public:
+ KoUnitDoubleComboBox( QWidget *parent = 0L, const char *name = 0L );
+ KoUnitDoubleComboBox( QWidget *parent, double lower, double upper, double value = 0.0, KoUnit::Unit unit = KoUnit::U_PT, unsigned int precision = 2, const char *name = 0 );
+
+ virtual void changeValue( double );
+ void updateValue( double );
+ virtual void setUnit( KoUnit::Unit = KoUnit::U_PT );
+
+ /// @return the current value, converted in points
+ double value( void ) const;
+ void insertItem( double, int index = -1 );
+
+protected:
+ bool eventFilter( QObject* obj, QEvent* ev );
+
+signals:
+ void valueChanged(double);
+
+private slots:
+ void slotActivated( int );
+
+protected:
+ double m_value;
+ double m_lower;
+ double m_upper;
+ double m_lowerInPoints; ///< lowest value in points
+ double m_upperInPoints; ///< highest value in points
+};
+
+/**
+ * Combo box (with spin control) for double precision numbers with unit display
+ * \since 1.4 (change of behavior)
+ */
+class KOFFICEUI_EXPORT KoUnitDoubleSpinComboBox : public QWidget
+{
+ Q_OBJECT
+public:
+ KoUnitDoubleSpinComboBox( QWidget *parent = 0L, const char *name = 0L );
+ KoUnitDoubleSpinComboBox( QWidget *parent, double lower, double upper, double step, double value = 0.0, KoUnit::Unit unit = KoUnit::U_PT, unsigned int precision = 2, const char *name = 0 );
+
+ void insertItem( double, int index = -1 );
+ void updateValue( double );
+ /// @return the current value, converted in points
+ double value( void ) const;
+
+signals:
+ void valueChanged(double);
+
+private slots:
+ void slotUpClicked();
+ void slotDownClicked();
+
+private:
+ KoUnitDoubleComboBox *m_combo;
+ double m_step;
+};
+
+#endif
+
diff --git a/lib/kofficeui/KoZoomAction.cpp b/lib/kofficeui/KoZoomAction.cpp
new file mode 100644
index 00000000..5f53f007
--- /dev/null
+++ b/lib/kofficeui/KoZoomAction.cpp
@@ -0,0 +1,115 @@
+/* This file is part of the KDE libraries
+ Copyright (C) 2004 Ariya Hidayat <ariya@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#include <KoZoomAction.h>
+
+#include <qstring.h>
+#include <qstringlist.h>
+#include <qregexp.h>
+#include <qvaluelist.h>
+
+#include <klocale.h>
+
+KoZoomAction::KoZoomAction( const QString& text, const QIconSet& pix,
+ const KShortcut& cut, QObject* parent, const char* name ):
+ KSelectAction( text, pix, cut, parent, name )
+{
+ init();
+}
+
+KoZoomAction::KoZoomAction( const QString& text, const QString& pix,
+ const KShortcut& cut, QObject* parent, const char* name ):
+ KSelectAction( text, pix, cut, parent, name )
+{
+ init();
+
+}
+
+void KoZoomAction::setZoom( const QString& text )
+{
+ bool ok = false;
+ QString t = text;
+ int zoom = t.remove( '%' ).toInt( &ok );
+
+ // where we'll store sorted new zoom values
+ QValueList<int> list;
+ if( zoom > 10 ) list.append( zoom );
+
+ // "Captured" non-empty sequence of digits
+ QRegExp regexp("(\\d+)");
+
+ const QStringList itemsList( items() );
+ for( QStringList::ConstIterator it = itemsList.begin(); it != itemsList.end(); ++it )
+ {
+ regexp.search( *it );
+ const int val=regexp.cap(1).toInt( &ok );
+
+ //zoom : limit inferior=10
+ if( ok && val>9 && list.contains( val )==0 )
+ list.append( val );
+ }
+
+ qHeapSort( list );
+
+ // update items with new sorted zoom values
+ QStringList values;
+ for (QValueList<int>::Iterator it = list.begin(); it != list.end(); ++it )
+ values.append( i18n("%1%").arg(*it) );
+ setItems( values );
+
+ QString zoomStr = i18n("%1%").arg( zoom );
+ setCurrentItem( values.findIndex( zoomStr ) );
+}
+
+void KoZoomAction::setZoom( int zoom )
+{
+ setZoom( QString::number( zoom ) );
+}
+
+void KoZoomAction::activated( const QString& text )
+{
+ setZoom( text );
+ emit zoomChanged( text );
+}
+
+void KoZoomAction::init()
+{
+ setEditable( true );
+
+ QStringList values;
+ values << i18n("%1%").arg("33");
+ values << i18n("%1%").arg("50");
+ values << i18n("%1%").arg("75");
+ values << i18n("%1%").arg("100");
+ values << i18n("%1%").arg("125");
+ values << i18n("%1%").arg("150");
+ values << i18n("%1%").arg("200");
+ values << i18n("%1%").arg("250");
+ values << i18n("%1%").arg("350");
+ values << i18n("%1%").arg("400");
+ values << i18n("%1%").arg("450");
+ values << i18n("%1%").arg("500");
+ setItems( values );
+
+ setCurrentItem( values.findIndex( i18n("%1%").arg( 100 ) ) );
+
+ connect( this, SIGNAL( activated( const QString& ) ),
+ SLOT( activated( const QString& ) ) );
+}
+
+#include "KoZoomAction.moc"
diff --git a/lib/kofficeui/KoZoomAction.h b/lib/kofficeui/KoZoomAction.h
new file mode 100644
index 00000000..326e4f04
--- /dev/null
+++ b/lib/kofficeui/KoZoomAction.h
@@ -0,0 +1,82 @@
+/* This file is part of the KDE libraries
+ Copyright (C) 2004 Ariya Hidayat <ariya@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#ifndef kozoomaction_h
+#define kozoomaction_h
+
+#include <kaction.h>
+#include <koffice_export.h>
+/**
+ * Class KoZoomAction implements an action to provide zoom values.
+ * In a toolbar, KoZoomAction will show a dropdown list, also with
+ * the possibility for the user to enter arbritrary zoom value
+ * (must be an integer). The values shown on the list are alwalys
+ * sorted.
+ */
+class KOFFICEUI_EXPORT KoZoomAction : public KSelectAction
+{
+Q_OBJECT
+
+public:
+
+ /**
+ * Creates a new zoom action.
+ */
+ KoZoomAction( const QString& text, const QIconSet& pix,
+ const KShortcut& cut = KShortcut(), QObject* parent = 0, const char* name = 0 );
+
+ /**
+ * Creates a new zoom action.
+ */
+ KoZoomAction( const QString& text, const QString& pix,
+ const KShortcut& cut = KShortcut(), QObject* parent = 0, const char* name = 0 );
+
+public slots:
+
+ /**
+ * Sets the zoom. If it's not yet on the list of zoom values, it will be inserted
+ * into the list at proper place so that the the values remain sorted.
+ */
+ void setZoom( const QString& zoom );
+
+ /**
+ * Sets the zoom. If it's not yet on the list of zoom values, it will be inserted
+ * into the list at proper place so that the the values remain sorted.
+ */
+ void setZoom( int zoom );
+
+protected slots:
+
+ void activated( const QString& text );
+
+signals:
+
+ /**
+ * Signal zoomChanged is triggered when user changes the zoom value, either by
+ * choosing it from the list or by entering new value.
+ */
+ void zoomChanged( const QString& zoom );
+
+protected:
+
+ void init();
+
+};
+
+
+#endif // kozoomaction_h
diff --git a/lib/kofficeui/KoZoomHandler.cpp b/lib/kofficeui/KoZoomHandler.cpp
new file mode 100644
index 00000000..2bb202e9
--- /dev/null
+++ b/lib/kofficeui/KoZoomHandler.cpp
@@ -0,0 +1,72 @@
+/* This file is part of the KDE project
+ Copyright (C) 2001-2005 David Faure <faure@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "KoZoomHandler.h"
+#include <kdebug.h>
+#include <KoUnit.h> // for POINT_TO_INCH
+#include <KoGlobal.h>
+
+KoZoomHandler::KoZoomHandler()
+{
+ // Note that this calls the method below, not the derived one
+ setZoomAndResolution( 100, KoGlobal::dpiX(), KoGlobal::dpiY() );
+}
+
+void KoZoomHandler::setZoomAndResolution( int zoom, int dpiX, int dpiY )
+{
+ // m_resolution[XY] is in pixel per pt
+ m_resolutionX = POINT_TO_INCH( static_cast<double>(dpiX) );
+ m_resolutionY = POINT_TO_INCH( static_cast<double>(dpiY) );
+ setZoom( zoom );
+ /*kdDebug(32500) << "KoZoomHandler::setZoomAndResolution " << zoom << " " << dpiX << "," << dpiY
+ << " m_resolutionX=" << m_resolutionX
+ << " m_zoomedResolutionX=" << m_zoomedResolutionX
+ << " m_resolutionY=" << m_resolutionY
+ << " m_zoomedResolutionY=" << m_zoomedResolutionY << endl;*/
+}
+
+void KoZoomHandler::setResolution( double resolutionX, double resolutionY )
+{
+ m_zoom = 100;
+ m_resolutionX = resolutionX;
+ m_resolutionY = resolutionY;
+ m_zoomedResolutionX = resolutionX;
+ m_zoomedResolutionY = resolutionY;
+}
+
+void KoZoomHandler::setZoomedResolution( double zoomedResolutionX, double zoomedResolutionY )
+{
+ // m_zoom doesn't matter, it's only used in setZoom() to calculated the zoomed resolutions
+ // Here we know them. The whole point of this method is to allow a different zoom factor
+ // for X and for Y, as can be useful for e.g. fullscreen kpresenter presentations.
+ m_zoomedResolutionX = zoomedResolutionX;
+ m_zoomedResolutionY = zoomedResolutionY;
+}
+
+void KoZoomHandler::setZoom( int zoom )
+{
+ m_zoom = zoom;
+ if( m_zoom == 100 ) {
+ m_zoomedResolutionX = m_resolutionX;
+ m_zoomedResolutionY = m_resolutionY;
+ } else {
+ m_zoomedResolutionX = static_cast<double>(m_zoom) * m_resolutionX / 100.0;
+ m_zoomedResolutionY = static_cast<double>(m_zoom) * m_resolutionY / 100.0;
+ }
+}
diff --git a/lib/kofficeui/KoZoomHandler.h b/lib/kofficeui/KoZoomHandler.h
new file mode 100644
index 00000000..903d2e11
--- /dev/null
+++ b/lib/kofficeui/KoZoomHandler.h
@@ -0,0 +1,163 @@
+/* This file is part of the KDE project
+ Copyright (C) 2001-2005 David Faure <faure@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef kozoomhandler_h
+#define kozoomhandler_h
+
+#include <KoRect.h>
+#include <koffice_export.h>
+#include <KoZoomMode.h>
+
+/**
+ * This class handles the zooming and DPI stuff (conversions between pt values and pixels).
+ * An instance of KoZoomHandler operates at a given zoom (see setZoomAndResolution() and setZoom())
+ * so there is usually one instance of KoZoomHandler per view.
+ */
+class KOFFICEUI_EXPORT KoZoomHandler
+{
+public:
+ KoZoomHandler();
+ virtual ~KoZoomHandler() {}
+
+ /**
+ * Change the zoom factor to @p z (e.g. 150 for 150%)
+ * and/or change the resolution, given in DPI.
+ * This is done on startup, when zooming, and when printing.
+ * The same call combines both so that all the updating done behind
+ * the scenes is done only once, even if both zoom and DPI must be changed.
+ */
+ virtual void setZoomAndResolution( int zoom, int dpiX, int dpiY );
+
+ /**
+ * @return the conversion factor between pt and pixel, that
+ * takes care of the zoom and the DPI setting.
+ * Use zoomIt(pt) instead, though.
+ */
+ double zoomedResolutionX() const { return m_zoomedResolutionX; }
+ double zoomedResolutionY() const { return m_zoomedResolutionY; }
+
+ double resolutionX() const { return m_resolutionX; }
+ double resolutionY() const { return m_resolutionY; }
+
+ /**
+ * Zoom factor for X. Equivalent to zoomedResolutionX()/resolutionX()
+ */
+ double zoomFactorX() const { return m_zoomedResolutionX / m_resolutionX; }
+ /**
+ * Zoom factor for Y. Equivalent to zoomedResolutionY()/resolutionY()
+ */
+ double zoomFactorY() const { return m_zoomedResolutionY / m_resolutionY; }
+
+
+ /**
+ * Set a resolution for X and Y, when no zoom applies (e.g. when painting an
+ * embedded document. This will set the zoom to 100, and it will set
+ * zoomedResolution[XY] to the resolution[XY] parameters
+ * Helper method, equivalent to setZoomAndResolution(100,...).
+ */
+ void setResolution( double resolutionX, double resolutionY );
+
+ /**
+ * Set the zoomed resolution for X and Y.
+ * Compared to the setZoom... methods, this allows to set a different
+ * zoom factor for X and for Y.
+ */
+ virtual void setZoomedResolution( double zoomedResolutionX, double zoomedResolutionY );
+
+ /**
+ * Change the zoom level, keeping the resolution unchanged.
+ * @param zoom the zoom factor (e.g. 100 for 100%)
+ */
+ void setZoom( int zoom );
+ /**
+ * Change the zoom mode
+ * @param zoomMode the zoom mode.
+ */
+ void setZoomMode( KoZoomMode::Mode zoomMode ) { m_zoomMode = zoomMode; }
+ /**
+ * @return the global zoom factor (e.g. 100 for 100%).
+ * Only use this to display to the user, don't use in calculations
+ */
+ int zoom() const { return m_zoom; }
+ /**
+ * @return the global zoom mode (e.g. KoZoomMode::ZOOM_WIDTH).
+ * use this to determine how to zoom
+ */
+ KoZoomMode::Mode zoomMode() const { return m_zoomMode; }
+
+ // Input: pt. Output: pixels. Resolution and zoom are applied.
+ int zoomItX( double z ) const {
+ return qRound( m_zoomedResolutionX * z );
+ }
+ int zoomItY( double z ) const {
+ return qRound( m_zoomedResolutionY * z );
+ }
+
+ QPoint zoomPoint( const KoPoint & p ) const {
+ return QPoint( zoomItX( p.x() ), zoomItY( p.y() ) );
+ }
+ QRect zoomRect( const KoRect & r ) const {
+ QRect _r;
+ _r.setCoords( zoomItX( r.left() ), zoomItY( r.top() ),
+ zoomItX( r.right() ), zoomItY( r.bottom() ) );
+ return _r;
+ }
+ /**
+ * Returns the size in pixels for a input size in points.
+ *
+ * This function can return a size with 1 pixel to less, depending
+ * on the reference point and the width and/or the zoom level.
+ * It's save to use if the starting point is (0/0).
+ * You can use it if you don't know the starting point yet
+ * (like when inserting a picture), but then please take
+ * care of it afterwards, when you know the reference point.
+ */
+ QSize zoomSize( const KoSize & s ) const {
+ return QSize( zoomItX( s.width() ), zoomItY( s.height() ) );
+ }
+
+ // Input: pixels. Output: pt.
+ double unzoomItX( int x ) const {
+ return static_cast<double>( x ) / m_zoomedResolutionX;
+ }
+ double unzoomItY( int y ) const {
+ return static_cast<double>( y ) / m_zoomedResolutionY;
+ }
+ KoPoint unzoomPoint( const QPoint & p ) const {
+ return KoPoint( unzoomItX( p.x() ), unzoomItY( p.y() ) );
+ }
+ KoRect unzoomRect( const QRect & r ) const {
+ KoRect _r;
+ _r.setCoords( unzoomItX( r.left() ), unzoomItY( r.top() ),
+ unzoomItX( r.right() ), unzoomItY( r.bottom() ) );
+ return _r;
+ }
+
+
+protected:
+ int m_zoom;
+ KoZoomMode::Mode m_zoomMode;
+
+ double m_resolutionX;
+ double m_resolutionY;
+ double m_zoomedResolutionX;
+ double m_zoomedResolutionY;
+};
+
+#endif
diff --git a/lib/kofficeui/KoZoomMode.cpp b/lib/kofficeui/KoZoomMode.cpp
new file mode 100644
index 00000000..4df4a7fa
--- /dev/null
+++ b/lib/kofficeui/KoZoomMode.cpp
@@ -0,0 +1,49 @@
+/* This file is part of the KDE project
+ Copyright (C) 2005 Johannes Schaub <litb_devel@web.de>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#include "KoZoomMode.h"
+#include <klocale.h>
+
+const char* KoZoomMode::modes[] =
+{
+ I18N_NOOP("Fit to Width"),
+ I18N_NOOP("Fit to Page"),
+ I18N_NOOP("%1%")
+};
+
+QString KoZoomMode::toString(Mode mode)
+{
+ return i18n(modes[mode]);
+}
+
+KoZoomMode::Mode KoZoomMode::toMode(const QString& mode)
+{
+ if(mode == i18n(modes[ZOOM_WIDTH]))
+ return ZOOM_WIDTH;
+ else
+ if(mode == i18n(modes[ZOOM_PAGE]))
+ return ZOOM_PAGE;
+ else
+ return ZOOM_CONSTANT;
+ // we return ZOOM_CONSTANT else because then we can pass '10%' or '15%'
+ // or whatever, it's automatically converted. ZOOM_CONSTANT is
+ // changable, whereas all other zoom modes (non-constants) are normal
+ // text like "Fit to xxx". they let the view grow/shrink according
+ // to windowsize, hence the term 'non-constant'
+}
diff --git a/lib/kofficeui/KoZoomMode.h b/lib/kofficeui/KoZoomMode.h
new file mode 100644
index 00000000..3e012f28
--- /dev/null
+++ b/lib/kofficeui/KoZoomMode.h
@@ -0,0 +1,54 @@
+/* This file is part of the KDE project
+ Copyright (C) 2005 Johannes Schaub <litb_devel@web.de>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#ifndef _KOZOOMMODE_H_
+#define _KOZOOMMODE_H_
+
+#include <qstring.h>
+#include "koffice_export.h"
+
+/**
+ * The ZoomMode container
+ */
+class KOFFICEUI_EXPORT KoZoomMode
+{
+public:
+ enum Mode
+ {
+ ZOOM_WIDTH = 0, ///< zoom pagewidth
+ ZOOM_PAGE = 1, ///< zoom to pagesize
+ ZOOM_CONSTANT = 2 ///< zoom x %
+ };
+
+ /// \param mode the mode name
+ /// \return the to Mode converted QString \c mode
+ static Mode toMode(const QString& mode);
+
+ /// \return the to QString converted and translated Mode \c mode
+ static QString toString(Mode mode);
+
+ /// \param mode the mode name
+ /// \return true if \c mode isn't dependent on windowsize
+ static bool isConstant(const QString& mode)
+ { return toMode(mode) == ZOOM_CONSTANT; }
+private:
+ static const char * modes[];
+};
+
+#endif
diff --git a/lib/kofficeui/Kolinestyleaction.cpp b/lib/kofficeui/Kolinestyleaction.cpp
new file mode 100644
index 00000000..da3415c7
--- /dev/null
+++ b/lib/kofficeui/Kolinestyleaction.cpp
@@ -0,0 +1,88 @@
+/* This file is part of the KDE project
+ Copyright (C) 2004 Peter Simonsson <psn@linux.se>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#include "Kolinestyleaction.h"
+
+#include <qpainter.h>
+#include <qpixmap.h>
+#include <qbitmap.h>
+
+#include <kpopupmenu.h>
+#include <kdebug.h>
+#include <klocale.h>
+
+class KoLineStyleAction::KoLineStyleActionPrivate
+{
+ public:
+ KoLineStyleActionPrivate()
+ {
+ m_currentStyle = Qt::SolidLine;
+ }
+
+ ~KoLineStyleActionPrivate()
+ {
+ }
+
+ int m_currentStyle;
+};
+
+KoLineStyleAction::KoLineStyleAction(const QString &text, const QString& icon,
+ QObject* parent, const char* name) : KoSelectAction(text, icon, parent, name)
+{
+ d = new KoLineStyleActionPrivate;
+
+ createMenu();
+}
+
+KoLineStyleAction::KoLineStyleAction(const QString &text, const QString& icon, const QObject* receiver,
+ const char* slot, QObject* parent, const char* name) : KoSelectAction(text, icon, receiver, slot, parent, name)
+{
+ d = new KoLineStyleActionPrivate;
+
+ createMenu();
+}
+
+KoLineStyleAction::~KoLineStyleAction()
+{
+ delete d;
+}
+
+void KoLineStyleAction::createMenu()
+{
+ KPopupMenu* popup = popupMenu();
+ QBitmap mask;
+ QPixmap pix(70, 21);
+ QPainter p(&pix, popup);
+ int cindex = 0;
+ QPen pen;
+ pen.setWidth(2);
+ popup->insertItem(i18n("None"),cindex++);
+
+ for(int i = 1; i < 6; i++) {
+ pix.fill(white);
+ pen.setStyle(static_cast<Qt::PenStyle>(i));
+ p.setPen(pen);
+ p.drawLine(0, 10, pix.width(), 10);
+ mask = pix;
+ pix.setMask(mask);
+ popup->insertItem(pix,cindex++);
+ }
+}
+
+#include "Kolinestyleaction.moc"
diff --git a/lib/kofficeui/Kolinestyleaction.h b/lib/kofficeui/Kolinestyleaction.h
new file mode 100644
index 00000000..ff8086f8
--- /dev/null
+++ b/lib/kofficeui/Kolinestyleaction.h
@@ -0,0 +1,58 @@
+/* This file is part of the KDE project
+ Copyright (C) 2004 Peter Simonsson <psn@linux.se>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KOLINESTYLEACTION_H
+#define KOLINESTYLEACTION_H
+
+#include "KoSelectAction.h"
+#include <koffice_export.h>
+/** A line style selection action */
+class KOFFICEUI_EXPORT KoLineStyleAction : public KoSelectAction
+{
+ Q_OBJECT
+ public:
+ /** Constructs a KoLineStyleAction with a text and an icon.
+ * @param text The text that will be displayed.
+ * @param icon The dynamically loaded icon that goes with this action.
+ * @param parent This action's parent.
+ * @param name An internal name for this action.
+ */
+ KoLineStyleAction(const QString& text, const QString& icon, QObject* parent = 0, const char* name = 0);
+ /** Same as above, but it also connects a slot to the selectionChanged(int) signal.
+ * @param text The text that will be displayed.
+ * @param icon The dynamically loaded icon that goes with this action.
+ * @param receiver The SLOT's parent.
+ * @param slot The SLOT to invoke when a selectionChanged(int) signal is emited.
+ * @param parent This action's parent.
+ * @param name An internal name for this action.
+ */
+ KoLineStyleAction(const QString& text, const QString& icon, const QObject* receiver,
+ const char* slot, QObject* parent, const char* name = 0);
+ ~KoLineStyleAction();
+
+ protected:
+ /** Draws and adds each item of the menu. */
+ void createMenu();
+
+ private:
+ class KoLineStyleActionPrivate;
+ KoLineStyleActionPrivate* d;
+};
+
+#endif
diff --git a/lib/kofficeui/Kolinewidthaction.cpp b/lib/kofficeui/Kolinewidthaction.cpp
new file mode 100644
index 00000000..611481cb
--- /dev/null
+++ b/lib/kofficeui/Kolinewidthaction.cpp
@@ -0,0 +1,200 @@
+/* This file is part of the KDE project
+ Copyright (C) 2004 Peter Simonsson <psn@linux.se>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#include "Kolinewidthaction.h"
+
+#include <qpainter.h>
+#include <qpixmap.h>
+#include <qbitmap.h>
+#include <qwhatsthis.h>
+#include <qmenubar.h>
+#include <qlayout.h>
+#include <qlabel.h>
+
+#include <kpopupmenu.h>
+#include <kapplication.h>
+#include <kdebug.h>
+#include <ktoolbar.h>
+#include <ktoolbarbutton.h>
+#include <kiconloader.h>
+#include <klocale.h>
+
+#include <KoUnitWidgets.h>
+#include <KoGlobal.h>
+
+class KoLineWidthAction::KoLineWidthActionPrivate
+{
+ public:
+ KoLineWidthActionPrivate()
+ {
+ m_currentWidth = 1.0;
+ m_unit = KoUnit::U_PT;
+ }
+
+ ~KoLineWidthActionPrivate()
+ {
+ }
+
+ double m_currentWidth;
+ KoUnit::Unit m_unit;
+};
+
+KoLineWidthAction::KoLineWidthAction(const QString &text, const QString& icon,
+ QObject* parent, const char* name) : KoSelectAction(text, icon, parent, name)
+{
+ d = new KoLineWidthActionPrivate;
+
+ createMenu();
+}
+
+KoLineWidthAction::KoLineWidthAction(const QString &text, const QString& icon, const QObject* receiver,
+ const char* slot, QObject* parent, const char* name) : KoSelectAction(text, icon, parent, name)
+{
+ d = new KoLineWidthActionPrivate;
+
+ createMenu();
+
+ connect(this, SIGNAL(lineWidthChanged(double)), receiver, slot);
+}
+
+KoLineWidthAction::~KoLineWidthAction()
+{
+ delete d;
+}
+
+void KoLineWidthAction::createMenu()
+{
+ KPopupMenu* popup = popupMenu();
+ QBitmap mask;
+ QPixmap pix(70, 21);
+ QPainter p(&pix, popup);
+ int cindex = 0;
+ QPen pen;
+
+ for(int i = 1; i <= 10; i++) {
+ pix.fill(white);
+ pen.setWidth(qRound(i * POINT_TO_INCH(static_cast<double>(KoGlobal::dpiY()))));
+ p.setPen(pen);
+ p.drawLine(0, 10, pix.width(), 10);
+ mask = pix;
+ pix.setMask(mask);
+ popup->insertItem(pix,cindex++);
+ }
+
+ popup->insertSeparator(cindex++);
+ popup->insertItem(i18n("&Custom..."), cindex++);
+}
+
+void KoLineWidthAction::execute(int index)
+{
+ bool ok = false;
+
+ if((index >= 0) && (index < 10)) {
+ d->m_currentWidth = (double) index + 1.0;
+ ok = true;
+ } if(index == 11) { // Custom width dialog...
+ KoLineWidthChooser dlg(qApp->activeWindow());
+ dlg.setUnit(d->m_unit);
+ dlg.setWidth(d->m_currentWidth);
+
+ if(dlg.exec()) {
+ d->m_currentWidth = dlg.width();
+ ok = true;
+ }
+ }
+
+ if(ok) {
+ setCurrentSelection(index);
+ emit lineWidthChanged(d->m_currentWidth);
+ }
+}
+
+double KoLineWidthAction::currentWidth() const
+{
+ return d->m_currentWidth;
+}
+
+void KoLineWidthAction::setCurrentWidth(double width)
+{
+ d->m_currentWidth = width;
+
+ // Check if it is a standard width...
+ for(int i = 1; i <= 10; i++) {
+ if(KoUnit::toPoint(width) == (double) i) {
+ setCurrentSelection(i - 1);
+ return;
+ }
+ }
+
+ //Custom width...
+ setCurrentSelection(11);
+}
+
+void KoLineWidthAction::setUnit(KoUnit::Unit unit)
+{
+ d->m_unit = unit;
+}
+
+//////////////////////////////////////////////////
+//
+// KoLineWidthChooser
+//
+
+class KoLineWidthChooser::KoLineWidthChooserPrivate
+{
+ public:
+ KoUnitDoubleSpinBox* m_lineWidthUSBox;
+};
+
+KoLineWidthChooser::KoLineWidthChooser(QWidget* parent, const char* name)
+ : KDialogBase(parent, name, true, i18n("Custom Line Width"), Ok|Cancel, Ok)
+{
+ d = new KoLineWidthChooserPrivate;
+
+ // Create the ui
+ QWidget* mainWidget = new QWidget(this);
+ setMainWidget(mainWidget);
+ QGridLayout* gl = new QGridLayout(mainWidget, 1, 2, KDialog::marginHint(), KDialog::spacingHint());
+ QLabel* textLbl = new QLabel(i18n("Line width:"), mainWidget);
+ d->m_lineWidthUSBox = new KoUnitDoubleSpinBox(mainWidget, 0.0, 1000.0, 0.1, 1.0, KoUnit::U_PT, 2);
+ gl->addWidget(textLbl, 0, 0);
+ gl->addWidget(d->m_lineWidthUSBox, 0, 1);
+}
+
+KoLineWidthChooser::~KoLineWidthChooser()
+{
+ delete d;
+}
+
+double KoLineWidthChooser::width() const
+{
+ return d->m_lineWidthUSBox->value();
+}
+
+void KoLineWidthChooser::setUnit(KoUnit::Unit unit)
+{
+ d->m_lineWidthUSBox->setUnit(unit);
+}
+
+void KoLineWidthChooser::setWidth(double width)
+{
+ d->m_lineWidthUSBox->changeValue(width);
+}
+
+#include "Kolinewidthaction.moc"
diff --git a/lib/kofficeui/Kolinewidthaction.h b/lib/kofficeui/Kolinewidthaction.h
new file mode 100644
index 00000000..fe03de72
--- /dev/null
+++ b/lib/kofficeui/Kolinewidthaction.h
@@ -0,0 +1,112 @@
+/* This file is part of the KDE project
+ Copyright (C) 2004 Peter Simonsson <psn@linux.se>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KOLINEWIDTHACTION_H
+#define KOLINEWIDTHACTION_H
+
+#include <kdialogbase.h>
+
+#include <KoUnit.h>
+#include <KoSelectAction.h>
+#include <koffice_export.h>
+
+/** A line width selection action */
+class KOFFICEUI_EXPORT KoLineWidthAction : public KoSelectAction
+{
+ Q_OBJECT
+ public:
+ /** Constructs a KoLineWidthAction with a text and an icon.
+ * @param text The text that will be displayed.
+ * @param icon The dynamically loaded icon that goes with this action.
+ * @param parent This action's parent.
+ * @param name An internal name for this action.
+ */
+ KoLineWidthAction(const QString& text, const QString& icon, QObject* parent = 0, const char* name = 0);
+ /** Same as above, but it also connects a slot to the selectionChanged(int) signal.
+ * @param text The text that will be displayed.
+ * @param icon The dynamically loaded icon that goes with this action.
+ * @param receiver The SLOT's parent.
+ * @param slot The SLOT to invoke when a lineWidthChanged(double) signal is emited.
+ * @param parent This action's parent.
+ * @param name An internal name for this action.
+ */
+ KoLineWidthAction(const QString& text, const QString& icon, const QObject* receiver,
+ const char* slot, QObject* parent, const char* name = 0);
+ ~KoLineWidthAction();
+
+ /** Returns the currently selected line width */
+ double currentWidth() const;
+
+ signals:
+ /** Emited when a new line width have been selected */
+ void lineWidthChanged(double);
+
+ public slots:
+ /** Set the current width.
+ * @param width The new width.
+ */
+ void setCurrentWidth(double width);
+ /** Set which unit to use in the custom width dialog.
+ * @param unit The unit to use.
+ */
+ void setUnit(KoUnit::Unit unit);
+
+ protected slots:
+ /** Reimplemented from KoSelectAction.
+ * Emits lineWidthChanged(double) when a new width is selected.
+ * @param index Index of the selected item
+ */
+ void execute(int index);
+
+ protected:
+ /** Draws and adds each item of the menu. */
+ void createMenu();
+
+ private:
+ class KoLineWidthActionPrivate;
+ KoLineWidthActionPrivate* d;
+};
+
+/** This class provides a dialog for setting a custom line width. */
+class KoLineWidthChooser : public KDialogBase
+{
+ Q_OBJECT
+ public:
+ KoLineWidthChooser(QWidget* parent = 0, const char* name = 0);
+ ~KoLineWidthChooser();
+
+ /** Returns the selected line width in points. */
+ double width() const;
+
+ public slots:
+ /** Set unit to use when showing the width.
+ * @param unit Unit to use.
+ */
+ void setUnit(KoUnit::Unit unit);
+ /** Set line width.
+ * @param width Line width in points.
+ */
+ void setWidth(double width);
+
+ private:
+ class KoLineWidthChooserPrivate;
+ KoLineWidthChooserPrivate* d;
+};
+
+#endif
diff --git a/lib/kofficeui/Makefile.am b/lib/kofficeui/Makefile.am
new file mode 100644
index 00000000..133673f2
--- /dev/null
+++ b/lib/kofficeui/Makefile.am
@@ -0,0 +1,61 @@
+###### General stuff
+
+KDE_CXXFLAGS = $(USE_RTTI) -DMAKE_KOFFICEUI_LIB
+INCLUDES = $(KSTORE_INCLUDES) $(KOFFICECORE_INCLUDES) $(all_includes)
+
+####### Files
+
+SUBDIRS = . tests pics
+
+lib_LTLIBRARIES = libkofficeui.la
+
+libkofficeui_la_SOURCES = \
+ KoPageLayoutDia.cpp KoZoomAction.cpp KoTabBar.cpp \
+ KoPartSelectDia.cpp KoPartSelectAction.cpp \
+ KoRuler.cpp KoTemplateChooseDia.cpp KoTabChooser.cpp \
+ KoKoolBar.cpp KoTemplateCreateDia.cpp KoContextCelp.cpp\
+ kcoloractions.cpp \
+ KoPictureFilePreview.cpp KoUnitWidgets.cpp \
+ tkaction.cpp tkcoloractions.cpp tkcombobox.cpp tktoolbarbutton.cpp \
+ KoCharSelectDia.cpp KoInsertLink.cpp KoEditPath.cpp KoCommandHistory.cpp \
+ KoSelectAction.cpp Kolinewidthaction.cpp Kolinestyleaction.cpp \
+ KoTooluButton.cpp \
+ KoBrush.cpp KoImageResource.cpp KoToolBox.cpp KoZoomHandler.cpp \
+ KoGuideLineDia.cpp KoGuides.cpp \
+ KoGeneralPropertyUi.ui KoPageLayoutColumns.cpp KoPageLayoutColumnsBase.ui KoPageLayoutSize.cpp \
+ KoPageLayoutHeaderBase.ui KoPageLayoutHeader.cpp KoPen.cpp KoZoomMode.cpp
+
+libkofficeui_la_LDFLAGS = -version-info 3:0:0 -no-undefined $(all_libraries)
+libkofficeui_la_LIBADD = $(LIB_KOFFICECORE)
+
+include_HEADERS = \
+ KoPageLayoutDia.h KoZoomAction.h KoTabBar.h \
+ KoPartSelectDia.h KoPartSelectAction.h \
+ KoRuler.h KoTemplateChooseDia.h KoTabChooser.h \
+ KoKoolBar.h KoTemplateCreateDia.h KoContextCelp.h \
+ kcoloractions.h \
+ KoPictureFilePreview.h KoUnitWidgets.h \
+ tkaction.h tkcoloractions.h tktoolbarbutton.h tkcombobox.h \
+ KoCharSelectDia.h KoInsertLink.h KoTooluButton.h KoEditPath.h \
+ KoCommandHistory.h KoImageResource.h \
+ KoSelectAction.h Kolinewidthaction.h Kolinestyleaction.h \
+ KoZoomHandler.h KoGuideLineDia.h KoGuides.h \
+ KoPageLayoutHeader.h KoPageLayoutSize.h KoGeneralPropertyUi.h KoPageLayoutColumns.h \
+ KoBrush.h KoPen.h KoZoomMode.h
+
+
+# FIXME: Disabled for now as it breaks the installation process if
+# KOffice is not installed in $KDEDIR
+#
+#AM_CXXFLAGS = -DQT_PLUGIN
+#kde_widget_LTLIBRARIES = kofficewidgets.la
+#kofficewidgets_la_LDFLAGS = $(KDE_PLUGIN) -module $(all_libraries)
+#kofficewidgets_la_LIBADD = $(LIB_KIO) libkofficeui.la
+#kofficewidgets_la_SOURCES = kofficewidgets.cpp
+
+#kofficewidgets.cpp: $(srcdir)/koffice.widgets
+# $(MAKEKDEWIDGETS) -o kofficewidgets.cpp $(srcdir)/koffice.widgets
+
+#CLEANFILES = kofficewidgets.cpp
+
+METASOURCES = AUTO
diff --git a/lib/kofficeui/kcoloractions.cpp b/lib/kofficeui/kcoloractions.cpp
new file mode 100644
index 00000000..a2d707d4
--- /dev/null
+++ b/lib/kofficeui/kcoloractions.cpp
@@ -0,0 +1,348 @@
+/* This file is part of the KDE libraries
+ Copyright (C) 2000 Reginald Stadlbauer <reggie@kde.org>
+ Copyright (C) 2002 Werner Trobin <trobin@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#include <kcoloractions.h>
+
+#include <qpopupmenu.h>
+#include <qwhatsthis.h>
+#include <qtooltip.h>
+
+#include <kapplication.h>
+#include <ktoolbar.h>
+#include <ktoolbarbutton.h>
+#include <kdebug.h>
+
+KColorAction::KColorAction( const QString& text, int accel,
+ QObject* parent, const char* name )
+ : KAction( text, accel, parent, name )
+{
+ typ = TextColor;
+ init();
+}
+
+KColorAction::KColorAction( const QString& text, int accel,
+ QObject* receiver, const char* slot, QObject* parent,
+ const char* name )
+ : KAction( text, accel, receiver, slot, parent, name )
+{
+ typ = TextColor;
+ init();
+}
+
+KColorAction::KColorAction( const QString& text, Type type, int accel,
+ QObject* parent, const char* name )
+ : KAction( text, accel, parent, name )
+{
+ typ = type;
+ init();
+}
+
+KColorAction::KColorAction( const QString& text, Type type, int accel,
+ QObject* receiver, const char* slot, QObject* parent,
+ const char* name )
+ : KAction( text, accel, receiver, slot, parent, name )
+{
+ typ = type;
+ init();
+}
+
+KColorAction::KColorAction( QObject* parent, const char* name )
+ : KAction( parent, name )
+{
+ typ = TextColor;
+ init();
+}
+
+void KColorAction::setColor( const QColor &c )
+{
+ if ( c == col )
+ return;
+
+ col = c;
+ createPixmap();
+}
+
+QColor KColorAction::color() const
+{
+ return col;
+}
+
+void KColorAction::setType( Type t )
+{
+ if ( t == typ )
+ return;
+
+ typ = t;
+ createPixmap();
+}
+
+KColorAction::Type KColorAction::type() const
+{
+ return typ;
+}
+
+void KColorAction::init()
+{
+ col = Qt::black;
+ createPixmap();
+}
+
+void KColorAction::createPixmap()
+{
+ int r, g, b;
+ QCString pix;
+ QCString line;
+
+ col.rgb( &r, &g, &b );
+
+ pix = "/* XPM */\n";
+
+ pix += "static char * text_xpm[] = {\n";
+
+ switch ( typ ) {
+ case TextColor: {
+ pix += "\"20 20 11 1\",\n";
+ pix += "\"h c #c0c000\",\n";
+ pix += "\"g c #808000\",\n";
+ pix += "\"f c #c0c0ff\",\n";
+ pix += "\"a c #000000\",\n";
+ pix += "\"d c #ff8000\",\n";
+ pix += "\". c none\",\n";
+ pix += "\"e c #0000c0\",\n";
+ pix += "\"i c #ffff00\",\n";
+ line.sprintf( "\"# c #%02X%02X%02X \",\n", r, g, b );
+ pix += line.copy();
+ pix += "\"b c #c00000\",\n";
+ pix += "\"c c #ff0000\",\n";
+ pix += "\"....................\",\n";
+ pix += "\"....................\",\n";
+ pix += "\"....................\",\n";
+ pix += "\"........#...........\",\n";
+ pix += "\"........#a..........\",\n";
+ pix += "\".......###..........\",\n";
+ pix += "\".......###a.........\",\n";
+ pix += "\"......##aa#.........\",\n";
+ pix += "\"......##a.#a........\",\n";
+ pix += "\".....##a...#........\",\n";
+ pix += "\".....#######a.......\",\n";
+ pix += "\"....##aaaaaa#.......\",\n";
+ pix += "\"....##a.....aaaaaaaa\",\n";
+ pix += "\"...####....#abbccdda\",\n";
+ pix += "\"....aaaa....abbccdda\",\n";
+ pix += "\"............aee##ffa\",\n";
+ pix += "\"............aee##ffa\",\n";
+ pix += "\"............agghhiia\",\n";
+ pix += "\"............agghhiia\",\n";
+ pix += "\"............aaaaaaaa\"};\n";
+ } break;
+ case FrameColor: {
+ pix += "\" 20 20 3 1 \",\n";
+
+ pix += "\" c none \",\n";
+ pix += "\"+ c white \",\n";
+ line.sprintf( "\". c #%02X%02X%02X \",\n", r, g, b );
+ pix += line.copy();
+
+ pix += "\" \",\n";
+ pix += "\" \",\n";
+ pix += "\" ................ \",\n";
+ pix += "\" ................ \",\n";
+ pix += "\" ................ \",\n";
+ pix += "\" ...++++++++++... \",\n";
+ pix += "\" ...++++++++++... \",\n";
+ pix += "\" ...++++++++++... \",\n";
+ pix += "\" ...++++++++++... \",\n";
+ pix += "\" ...++++++++++... \",\n";
+ pix += "\" ...++++++++++... \",\n";
+ pix += "\" ...++++++++++... \",\n";
+ pix += "\" ...++++++++++... \",\n";
+ pix += "\" ...++++++++++... \",\n";
+ pix += "\" ...++++++++++... \",\n";
+ pix += "\" ................ \",\n";
+ pix += "\" ................ \",\n";
+ pix += "\" ................ \",\n";
+ pix += "\" \",\n";
+ pix += "\" \";\n";
+ } break;
+ case BackgroundColor: {
+ pix += "\" 20 20 3 1 \",\n";
+
+ pix += "\" c none \",\n";
+ pix += "\". c red \",\n";
+ line.sprintf( "\"+ c #%02X%02X%02X \",\n", r, g, b );
+ pix += line.copy();
+
+ pix += "\" \",\n";
+ pix += "\" \",\n";
+ pix += "\" ................ \",\n";
+ pix += "\" ................ \",\n";
+ pix += "\" ..++++++++++++.. \",\n";
+ pix += "\" ..++++++++++++.. \",\n";
+ pix += "\" ..++++++++++++.. \",\n";
+ pix += "\" ..++++++++++++.. \",\n";
+ pix += "\" ..++++++++++++.. \",\n";
+ pix += "\" ..++++++++++++.. \",\n";
+ pix += "\" ..++++++++++++.. \",\n";
+ pix += "\" ..++++++++++++.. \",\n";
+ pix += "\" ..++++++++++++.. \",\n";
+ pix += "\" ..++++++++++++.. \",\n";
+ pix += "\" ..++++++++++++.. \",\n";
+ pix += "\" ..++++++++++++.. \",\n";
+ pix += "\" ................ \",\n";
+ pix += "\" ................ \",\n";
+ pix += "\" \",\n";
+ pix += "\" \";\n";
+ } break;
+ }
+
+ QPixmap pixmap( pix );
+ setIconSet( QIconSet( pixmap ) );
+}
+
+
+KSelectColorAction::KSelectColorAction( const QString& text, Type type,
+ const QObject* receiver, const char* slot,
+ KActionCollection* parent, const char* name ) :
+ KAction( text, KShortcut(), receiver, slot, parent, name ), m_type( type ),
+ m_color( Qt::black )
+{
+}
+
+KSelectColorAction::~KSelectColorAction()
+{
+}
+
+int KSelectColorAction::plug( QWidget* w, int index )
+{
+ if (w == 0) {
+ kdWarning() << "KSelectColorAction::plug called with 0 argument\n";
+ return -1;
+ }
+ if (kapp && !kapp->authorizeKAction(name()))
+ return -1;
+
+ if ( w->inherits("QPopupMenu") )
+ {
+ QPopupMenu* menu = static_cast<QPopupMenu*>( w );
+ int id;
+
+ if ( hasIcon() )
+ {
+ /* ###### CHECK: We're not allowed to specify the instance in iconSet()
+ KInstance *instance;
+ if ( parentCollection() )
+ instance = parentCollection()->instance();
+ else
+ instance = KGlobal::instance();
+ */
+ id = menu->insertItem( iconSet( KIcon::Small, 0 ), text(), this,//dsweet
+ SLOT( slotActivated() ), 0, -1, index );
+ }
+ else
+ id = menu->insertItem( text(), this, SLOT( slotActivated() ), //dsweet
+ 0, -1, index );
+
+ updateShortcut( menu, id );
+
+ // call setItemEnabled only if the item really should be disabled,
+ // because that method is slow and the item is per default enabled
+ if ( !isEnabled() )
+ menu->setItemEnabled( id, false );
+
+ if ( !whatsThis().isEmpty() )
+ menu->setWhatsThis( id, whatsThisWithIcon() );
+
+ addContainer( menu, id );
+ connect( menu, SIGNAL( destroyed() ), this, SLOT( slotDestroyed() ) );
+
+ if ( parentCollection() )
+ parentCollection()->connectHighlight( menu, this );
+
+ return containerCount() - 1;
+ }
+ else if ( w->inherits( "KToolBar" ) )
+ {
+ KToolBar *bar = static_cast<KToolBar *>( w );
+
+ int id_ = getToolButtonID();
+ KInstance *instance;
+ if ( parentCollection() )
+ instance = parentCollection()->instance();
+ else
+ instance = KGlobal::instance();
+
+ if ( icon().isEmpty() ) // old code using QIconSet directly
+ {
+ bar->insertButton( iconSet( KIcon::Small ).pixmap(), id_, SIGNAL( clicked() ), this,
+ SLOT( slotActivated() ),
+ isEnabled(), plainText(), index );
+ }
+ else
+ bar->insertButton( icon(), id_, SIGNAL( clicked() ), this,
+ SLOT( slotActivated() ),
+ isEnabled(), plainText(), index, instance );
+
+ bar->getButton( id_ )->setName( QCString("toolbutton_")+name() );
+
+ if ( !whatsThis().isEmpty() )
+ QWhatsThis::add( bar->getButton(id_), whatsThisWithIcon() );
+
+ if ( !toolTip().isEmpty() )
+ QToolTip::add( bar->getButton(id_), toolTip() );
+
+ addContainer( bar, id_ );
+
+ connect( bar, SIGNAL( destroyed() ), this, SLOT( slotDestroyed() ) );
+
+ if ( parentCollection() )
+ parentCollection()->connectHighlight( bar, this );
+
+ return containerCount() - 1;
+ }
+
+ return -1;
+}
+
+QColor KSelectColorAction::color() const
+{
+ return m_color;
+}
+
+KSelectColorAction::Type KSelectColorAction::type() const
+{
+ return m_type;
+}
+
+void KSelectColorAction::setColor( const QColor &/*c*/ )
+{
+}
+
+void KSelectColorAction::setType( Type /*t*/ )
+{
+}
+
+QString KSelectColorAction::whatsThisWithIcon() const
+{
+ QString text = whatsThis();
+ if (!icon().isEmpty())
+ return QString::fromLatin1("<img source=\"small|%1\"> %2").arg(icon()).arg(text);
+ return text;
+}
+
+#include <kcoloractions.moc>
diff --git a/lib/kofficeui/kcoloractions.h b/lib/kofficeui/kcoloractions.h
new file mode 100644
index 00000000..b20be747
--- /dev/null
+++ b/lib/kofficeui/kcoloractions.h
@@ -0,0 +1,101 @@
+/* This file is part of the KDE libraries
+ Copyright (C) 2000 Reginald Stadlbauer <reggie@kde.org>
+ Copyright (C) 2002 Werner Trobin <trobin@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#ifndef kcoloractions_h
+#define kcoloractions_h
+
+#include <kaction.h>
+
+/**
+ * An action whose pixmap is automatically generated from a color.
+ * It knows three types of pixmaps: text color, frame color and background color
+ */
+class KColorAction : public KAction
+{
+ Q_OBJECT
+
+public:
+ enum Type {
+ TextColor,
+ FrameColor,
+ BackgroundColor
+ };
+
+ // Create default (text) color action
+ KColorAction( const QString& text, int accel = 0, QObject* parent = 0, const char* name = 0 );
+ KColorAction( const QString& text, int accel,
+ QObject* receiver, const char* slot, QObject* parent, const char* name = 0 );
+ KColorAction( QObject* parent = 0, const char* name = 0 );
+
+ // Create a color action of a given type
+ KColorAction( const QString& text, Type type, int accel = 0,
+ QObject* parent = 0, const char* name = 0 );
+ KColorAction( const QString& text, Type type, int accel,
+ QObject* receiver, const char* slot, QObject* parent, const char* name = 0 );
+
+ virtual void setColor( const QColor &c );
+ QColor color() const;
+
+ virtual void setType( Type type );
+ Type type() const;
+
+private:
+ void init();
+ void createPixmap();
+
+ QColor col;
+ Type typ;
+};
+
+
+class KSelectColorAction : public KAction
+{
+ Q_OBJECT
+public:
+ enum Type {
+ TextColor,
+ LineColor,
+ FillColor
+ };
+
+ KSelectColorAction( const QString& text, Type type,
+ const QObject* receiver, const char* slot,
+ KActionCollection* parent, const char* name );
+ virtual ~KSelectColorAction();
+
+ virtual int plug( QWidget* w, int index = -1 );
+
+ QColor color() const;
+ Type type() const;
+
+public slots:
+ virtual void setColor( const QColor &c );
+ virtual void setType( Type t );
+
+signals:
+ void colorSelected( const QColor& color );
+
+private:
+ QString whatsThisWithIcon() const; // duplicated, as it's private in kaction
+
+ Type m_type;
+ QColor m_color;
+};
+
+#endif
diff --git a/lib/kofficeui/koffice.widgets b/lib/kofficeui/koffice.widgets
new file mode 100644
index 00000000..9a3f0ba1
--- /dev/null
+++ b/lib/kofficeui/koffice.widgets
@@ -0,0 +1,32 @@
+[Global]
+PluginName=KOfficeWidgets
+
+[KoBuggyUnitDoubleSpinBox]
+ToolTip=KOffice Spin box for double precision numbers with unit display
+WhatsThis=KOffice Spin box for double precision numbers with unit display
+IncludeFile=koUnitWidgets.h
+Group=Input (KOffice)
+
+[KoUnitDoubleSpinBox2]
+ToolTip=KOffice Spin box for double precision numbers with unit display
+WhatsThis=KOffice Spin box for double precision numbers with unit display
+IncludeFile=koUnitWidgets.h
+Group=Input (KOffice)
+
+[KoUnitDoubleLineEdit]
+ToolTip=KOffice Line edit for double precision numbers with unit display
+WhatsThis=KOffice Line edit for double precision numbers with unit display
+IncludeFile=koUnitWidgets.h
+Group=Input (KOffice)
+
+[KoUnitDoubleComboBox]
+ToolTip=KOffice Combo box for double precision numbers with unit display
+WhatsThis=KOffice Combo box for double precision numbers with unit display
+IncludeFile=koUnitWidgets.h
+Group=Input (KOffice)
+
+[KoUnitDoubleSpinComboBox]
+ToolTip=KOffice Combo box (with spin control) for double precision numbers with unit display
+WhatsThis=KOffice Combo box (with spin control) for double precision numbers with unit display
+IncludeFile=koUnitWidgets.h
+Group=Input (KOffice)
diff --git a/lib/kofficeui/pics/Makefile.am b/lib/kofficeui/pics/Makefile.am
new file mode 100644
index 00000000..a7f2e664
--- /dev/null
+++ b/lib/kofficeui/pics/Makefile.am
@@ -0,0 +1,12 @@
+
+picsdir = $(kde_datadir)/koffice/pics
+pics_DATA = koRulerFirst.png koRulerLeft.png koffice-logo.png \
+ koKoolBarDown.png koKoolBarUp.png \
+ koPortrait.png koLandscape.png
+
+kofficewidgetsdata_DATA = kounitdoublecombobox.png kounitdoublelineedit.png \
+ kounitdoublespinbox2.png kounitdoublespincombobox.png
+
+kofficewidgetsdatadir = $(kde_datadir)/kofficewidgets/pics
+
+EXTRA_DIST = $(kofficewidgetsdata_DATA)
diff --git a/lib/kofficeui/pics/koKoolBarDown.png b/lib/kofficeui/pics/koKoolBarDown.png
new file mode 100644
index 00000000..621e4afd
--- /dev/null
+++ b/lib/kofficeui/pics/koKoolBarDown.png
Binary files differ
diff --git a/lib/kofficeui/pics/koKoolBarUp.png b/lib/kofficeui/pics/koKoolBarUp.png
new file mode 100644
index 00000000..513f6a1d
--- /dev/null
+++ b/lib/kofficeui/pics/koKoolBarUp.png
Binary files differ
diff --git a/lib/kofficeui/pics/koLandscape.png b/lib/kofficeui/pics/koLandscape.png
new file mode 100644
index 00000000..63daed42
--- /dev/null
+++ b/lib/kofficeui/pics/koLandscape.png
Binary files differ
diff --git a/lib/kofficeui/pics/koPortrait.png b/lib/kofficeui/pics/koPortrait.png
new file mode 100644
index 00000000..b0e28bdb
--- /dev/null
+++ b/lib/kofficeui/pics/koPortrait.png
Binary files differ
diff --git a/lib/kofficeui/pics/koRulerFirst.png b/lib/kofficeui/pics/koRulerFirst.png
new file mode 100644
index 00000000..bc9957cf
--- /dev/null
+++ b/lib/kofficeui/pics/koRulerFirst.png
Binary files differ
diff --git a/lib/kofficeui/pics/koRulerLeft.png b/lib/kofficeui/pics/koRulerLeft.png
new file mode 100644
index 00000000..0b117a04
--- /dev/null
+++ b/lib/kofficeui/pics/koRulerLeft.png
Binary files differ
diff --git a/lib/kofficeui/pics/koffice-logo.png b/lib/kofficeui/pics/koffice-logo.png
new file mode 100644
index 00000000..fd8e3a86
--- /dev/null
+++ b/lib/kofficeui/pics/koffice-logo.png
Binary files differ
diff --git a/lib/kofficeui/pics/kounitdoublecombobox.png b/lib/kofficeui/pics/kounitdoublecombobox.png
new file mode 100644
index 00000000..79efbbfa
--- /dev/null
+++ b/lib/kofficeui/pics/kounitdoublecombobox.png
Binary files differ
diff --git a/lib/kofficeui/pics/kounitdoublelineedit.png b/lib/kofficeui/pics/kounitdoublelineedit.png
new file mode 100644
index 00000000..a3bce54a
--- /dev/null
+++ b/lib/kofficeui/pics/kounitdoublelineedit.png
Binary files differ
diff --git a/lib/kofficeui/pics/kounitdoublespinbox2.png b/lib/kofficeui/pics/kounitdoublespinbox2.png
new file mode 100644
index 00000000..e1da718c
--- /dev/null
+++ b/lib/kofficeui/pics/kounitdoublespinbox2.png
Binary files differ
diff --git a/lib/kofficeui/pics/kounitdoublespincombobox.png b/lib/kofficeui/pics/kounitdoublespincombobox.png
new file mode 100644
index 00000000..79efbbfa
--- /dev/null
+++ b/lib/kofficeui/pics/kounitdoublespincombobox.png
Binary files differ
diff --git a/lib/kofficeui/tests/Makefile.am b/lib/kofficeui/tests/Makefile.am
new file mode 100644
index 00000000..2aa13645
--- /dev/null
+++ b/lib/kofficeui/tests/Makefile.am
@@ -0,0 +1,15 @@
+####### General stuff
+
+INCLUDES= -I$(srcdir)/.. $(KOFFICECORE_INCLUDES) $(all_includes)
+
+####### Files
+
+METASOURCES = AUTO
+
+check_PROGRAMS = # coloraction_test
+
+TESTS =
+
+#coloraction_test_SOURCES = coloraction_test.cpp
+#coloraction_test_LDADD = ../libkofficeui.la
+
diff --git a/lib/kofficeui/tests/coloraction_test.cpp b/lib/kofficeui/tests/coloraction_test.cpp
new file mode 100644
index 00000000..538f9707
--- /dev/null
+++ b/lib/kofficeui/tests/coloraction_test.cpp
@@ -0,0 +1,112 @@
+/* This file is part of the KDE project
+ Copyright (C) 1999 by Dirk A. Mueller <dmuell@gmx.net>
+ Copyright (C) 2002 Werner Trobin <trobin@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#include <qlayout.h>
+#include <qvgroupbox.h>
+#include <qpopupmenu.h>
+#include <qmenubar.h>
+
+#include <kdebug.h>
+#include <ktoolbar.h>
+#include <kiconloader.h>
+#include <kapplication.h>
+#include <KoTooluButton.h>
+#include <coloraction_test.h>
+
+#include <stdlib.h>
+#include <time.h>
+
+
+TopLevel::TopLevel( QWidget* parent, const char* name) : QMainWindow( parent, name )
+{
+ setCaption( QString::fromLatin1( "KColorAction test application" ) );
+
+ QWidget *w = new QWidget( this );
+ setCentralWidget( w );
+
+ QBoxLayout* l = new QHBoxLayout( w, KDialog::marginHint(), KDialog::spacingHint() );
+ QGroupBox* b1 = new QVGroupBox( QString::fromLatin1( "KoColorPanel 1" ), w );
+ panel = new KoColorPanel( b1, "panel1" );
+ connect( panel, SIGNAL( colorSelected( const QColor& ) ), SLOT( slotColorSelected( const QColor& ) ) );
+ //panel->insertDefaultColors();
+ l->addWidget( b1 );
+
+ b1 = new QVGroupBox( QString::fromLatin1( "KoColorPanel 2" ), w );
+
+ ( void ) new KoColorPanel( b1, "panel2" );
+ l->addWidget( b1 );
+
+ QPopupMenu* file = new QPopupMenu( this );
+ menuBar()->insertItem( "&File", file );
+
+ file->insertItem( "Custom + Default", KoColorPanel::createColorPopup( KoColorPanel::CustomColors, Qt::red, this,
+ SLOT( slotColorSelected( const QColor& ) ), file, "blah" ) );
+ file->insertItem( "Custom", KoColorPanel::createColorPopup( KoColorPanel::CustomColors, QColor(), this,
+ SLOT( slotColorSelected( const QColor& ) ), file, "blah" ) );
+ file->insertItem( "Plain + Default", KoColorPanel::createColorPopup( KoColorPanel::Plain, Qt::green, this,
+ SLOT( slotColorSelected( const QColor& ) ), file, "blah" ) );
+ file->insertItem( "Plain", KoColorPanel::createColorPopup( KoColorPanel::Plain, QColor(), this,
+ SLOT( slotColorSelected( const QColor& ) ), file, "blah" ) );
+ file->insertSeparator();
+ file->insertItem( "Default Colors", this, SLOT( defaultColors() ), CTRL+Key_D );
+ file->insertItem( "Insert Random Color", this, SLOT( insertRandomColor() ), CTRL+Key_R );
+ file->insertSeparator();
+ file->insertItem( "Clear", this, SLOT( clearColors() ), CTRL+Key_C );
+ file->insertSeparator();
+ file->insertItem( "&Quit", qApp, SLOT( closeAllWindows() ), CTRL+Key_Q );
+
+ KToolBar* toolBar = new KToolBar( this );
+ addDockWindow( toolBar );
+ ( void ) new KoToolButton( "color_fill", 1, toolBar, "funky button", "Fill Color" );
+}
+
+void TopLevel::insertRandomColor()
+{
+ panel->insertColor( qRgb( rand() % 256, rand() % 256, rand() % 256 ) );
+}
+
+void TopLevel::defaultColors()
+{
+ panel->insertDefaultColors();
+}
+
+void TopLevel::clearColors()
+{
+ panel->clear();
+}
+
+void TopLevel::slotColorSelected( const QColor& color )
+{
+ kdDebug() << "#### selected: " << color.name() << endl;
+}
+
+
+int main( int argc, char ** argv )
+{
+ srand( time( 0 ) );
+
+ KApplication a( argc, argv, "KColorAction Test" );
+ TopLevel *toplevel = new TopLevel( 0, "coloractiontest" );
+ a.setMainWidget( toplevel );
+ toplevel->show();
+ return a.exec();
+}
+
+#include <coloraction_test.moc>
diff --git a/lib/kofficeui/tests/coloraction_test.h b/lib/kofficeui/tests/coloraction_test.h
new file mode 100644
index 00000000..d29f9c5a
--- /dev/null
+++ b/lib/kofficeui/tests/coloraction_test.h
@@ -0,0 +1,44 @@
+/* This file is part of the KDE project
+ Copyright (C) 1999 by Dirk A. Mueller <dmuell@gmx.net>
+ Copyright (C) 2002 Werner Trobin <trobin@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#ifndef _COLORACTIONTEST_H
+#define _COLORACTIONTEST_H
+
+#include <qmainwindow.h>
+
+class KoColorPanel;
+
+class TopLevel : public QMainWindow
+{
+ Q_OBJECT
+public:
+ TopLevel( QWidget* parent = 0, const char* name = 0 );
+
+public slots:
+ void insertRandomColor();
+ void defaultColors();
+ void clearColors();
+ void slotColorSelected( const QColor& color );
+
+private:
+ KoColorPanel* panel;
+};
+
+#endif // _COLORACTIONTEST_H
diff --git a/lib/kofficeui/tkaction.cpp b/lib/kofficeui/tkaction.cpp
new file mode 100644
index 00000000..f627df56
--- /dev/null
+++ b/lib/kofficeui/tkaction.cpp
@@ -0,0 +1,300 @@
+/*
+ * Kivio - Visual Modelling and Flowcharting
+ * Copyright (C) 2000 theKompany.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+#include "tkaction.h"
+#include "tktoolbarbutton.h"
+#include "tkcombobox.h"
+
+#include <qlabel.h>
+#include <qlayout.h>
+
+#include <ktoolbar.h>
+#include <kiconloader.h>
+
+#define SET_FOR_ALL_CONTAINER(WIDGET_TYPE,METHOD_NAME,VALUE) \
+ for( int id = 0; id < containerCount(); ++id ) { \
+ QWidget* w = container(id); \
+ if ( w->inherits("KToolBar") ) { \
+ QWidget* r = static_cast<KToolBar*>(w)->getWidget(itemId(id)); \
+ if (qstrcmp(r->name(),"KTToolBarLayout")==0) \
+ r = (QWidget*)r->child("widget"); \
+ if ( r && r->inherits(#WIDGET_TYPE) ) { \
+ WIDGET_TYPE* b = static_cast<WIDGET_TYPE*>(r); \
+ b->METHOD_NAME(VALUE); \
+ } \
+ } \
+ }
+
+TKAction::TKAction(QObject* parent, const char* name)
+: KAction( "", 0, parent, name )
+{
+ m_imode = TK::IconOnly;
+}
+
+TKAction::~TKAction()
+{
+}
+
+int TKAction::plug(QWidget* widget, int index)
+{
+ if ( widget->inherits("KToolBar") ) {
+ KToolBar* bar = static_cast<KToolBar*>(widget);
+ int id_ = KAction::getToolButtonID();
+ KInstance *instance;
+
+ if ( parentCollection() )
+ instance = parentCollection()->instance();
+ else
+ instance = KGlobal::instance();
+
+ TKToolBarButton* b = new TKToolBarButton(icon(),plainText(),bar,name(),instance);
+ // we don't need clicked() and buttonClicked(), do we?
+ // connect(b,SIGNAL(clicked()),SLOT(slotActivated()));
+ b->setIconMode(m_imode);
+ initToolBarButton(b);
+
+ bar->insertWidget( id_, 100, b, index );
+ addContainer(bar,id_);
+ connect( bar, SIGNAL(destroyed()), this, SLOT(slotDestroyed()) );
+
+ return containerCount() - 1;
+ }
+ return KAction::plug(widget,index);
+}
+
+void TKAction::initToolBarButton(TKToolBarButton* button)
+{
+ connect(button,SIGNAL(buttonClicked()),SLOT(slotActivated()));
+}
+
+TK::IconMode TKAction::iconMode()
+{
+ return m_imode;
+}
+
+void TKAction::setIconMode(TK::IconMode mode)
+{
+ m_imode = mode;
+ SET_FOR_ALL_CONTAINER(TKToolBarButton,setIconMode,mode)
+}
+
+void TKAction::setText(const QString& text)
+{
+ KAction::setText(text);
+ updateLayout();
+}
+
+void TKAction::setIcon(const QString& icon)
+{
+ KAction::setIcon(icon);
+ updateLayout();
+}
+
+void TKAction::updateLayout()
+{
+ int len = containerCount();
+ for( int id = 0; id < len; ++id ) {
+ QWidget* w = container( id );
+ if (w->inherits("KToolBar")) {
+ QWidget* r = static_cast<KToolBar*>(w)->getWidget(itemId(id));
+ if (qstrcmp(r->name(),"KTToolBarLayout")==0) {
+ updateLayout(r);
+ }
+ }
+ }
+}
+
+QWidget* TKAction::createLayout(QWidget* parent, QWidget* children)
+{
+ QWidget* base = new QWidget(parent,"KTToolBarLayout");
+ QLabel* textLabel = new QLabel(base,"text");
+ textLabel->setMinimumHeight(1);
+ QLabel* pixLabel = new QLabel(base,"pixmap");
+ children->reparent(base,QPoint(0,0));
+ children->setName("widget");
+ QHBoxLayout* layout = new QHBoxLayout(base,0,3);
+ layout->setResizeMode(QLayout::Minimum);
+ layout->addWidget(textLabel);
+ layout->addWidget(pixLabel);
+ layout->addWidget(children,1);
+
+ updateLayout(base);
+ return base;
+}
+
+void TKAction::updateLayout(QWidget* base)
+{
+ QLabel* textLabel = (QLabel*)base->child("text");
+ QLabel* pixLabel = (QLabel*)base->child("pixmap");
+ QWidget* w = (QWidget*)base->child("widget");
+
+ if (!textLabel || !pixLabel || !w)
+ return;
+
+ if (!text().isEmpty() && m_imode != TK::IconOnly ) {
+ textLabel->setText(text());
+ textLabel->show();
+ } else
+ textLabel->hide();
+
+ QPixmap pix;
+ if (hasIcon())
+ pix = iconSet(KIcon::Small).pixmap();
+
+ if (!icon().isEmpty())
+ pix = BarIcon(icon());
+
+ if (!pix.isNull() && m_imode != TK::TextOnly) {
+ pixLabel->setPixmap(pix);
+ pixLabel->show();
+ } else
+ pixLabel->hide();
+
+ base->setFixedWidth( w->sizeHint().width() +
+ (textLabel->isVisible() ? textLabel->sizeHint().width():0) +
+ (pixLabel->isVisible() ? pixLabel->sizeHint().width():0) );
+}
+/******************************************************************************/
+TKBaseSelectAction::TKBaseSelectAction( QObject* parent, const char* name )
+: TKAction(parent,name)
+{
+ m_current = 0;
+ m_editable = false;
+}
+
+TKBaseSelectAction::~TKBaseSelectAction()
+{
+}
+
+int TKBaseSelectAction::plug(QWidget* widget, int index)
+{
+ if ( widget->inherits("KToolBar") )
+ {
+ KToolBar* bar = static_cast<KToolBar*>( widget );
+ int id_ = KAction::getToolButtonID();
+
+ TKComboBox* cb = new TKComboBox(m_editable,bar);
+ initComboBox(cb);
+ cb->setMinimumWidth( cb->sizeHint().width() );
+ QWidget* base = createLayout(bar,cb);
+
+ bar->insertWidget( id_, 100, base, index );
+ addContainer( bar, id_ );
+
+ connect( bar, SIGNAL( destroyed() ), this, SLOT( slotDestroyed() ) );
+
+ setCurrentItem(currentItem());
+
+ return containerCount() - 1;
+ }
+ return -1;
+}
+
+int TKBaseSelectAction::currentItem()
+{
+ return m_current;
+}
+
+void TKBaseSelectAction::initComboBox(TKComboBox* cb)
+{
+ connect(cb,SIGNAL(activated(int)),SLOT(slotActivated(int)));
+}
+
+void TKBaseSelectAction::setEditable(bool editable)
+{
+ m_editable = editable;
+ SET_FOR_ALL_CONTAINER(TKComboBox,setEditable,editable)
+}
+
+bool TKBaseSelectAction::isEditable()
+{
+ return m_editable;
+}
+
+void TKBaseSelectAction::setCurrentItem(int index)
+{
+ m_current = index;
+ SET_FOR_ALL_CONTAINER(TKComboBox,setCurrentItem,index)
+}
+
+void TKBaseSelectAction::slotActivated(int id)
+{
+ if ( m_current == id )
+ return;
+
+ m_current = id;
+ setCurrentItem(id);
+ activate(id);
+}
+
+void TKBaseSelectAction::activate(int id)
+{
+ emit activated(id);
+}
+/******************************************************************************/
+TKSelectAction::TKSelectAction( QObject* parent, const char* name )
+: TKBaseSelectAction(parent,name)
+{
+}
+
+TKSelectAction::~TKSelectAction()
+{
+}
+
+void TKSelectAction::initComboBox(TKComboBox* cb)
+{
+ TKBaseSelectAction::initComboBox(cb);
+ connect(cb,SIGNAL(activated(const QString&)),SLOT(slotActivated(const QString&)));
+ cb->insertStringList(items());
+}
+
+void TKSelectAction::slotActivated(const QString& text)
+{
+ emit activated(text);
+}
+
+void TKSelectAction::setItems(const QStringList& lst )
+{
+ m_list = lst;
+ m_current = -1;
+
+ SET_FOR_ALL_CONTAINER(TKComboBox,clear, )
+ SET_FOR_ALL_CONTAINER(TKComboBox,insertStringList,lst)
+
+ // Disable if empty and not editable
+ setEnabled ( lst.count() > 0 || m_editable );
+}
+
+QStringList TKSelectAction::items() const
+{
+ return m_list;
+}
+
+void TKSelectAction::clear()
+{
+ SET_FOR_ALL_CONTAINER(TKComboBox,clear, )
+}
+
+void TKSelectAction::setEditText(const QString& text)
+{
+ SET_FOR_ALL_CONTAINER(TKComboBox,setEditText,text)
+}
+
+#undef SET_FOR_ALL_CONTAINER
+#include "tkaction.moc"
diff --git a/lib/kofficeui/tkaction.h b/lib/kofficeui/tkaction.h
new file mode 100644
index 00000000..648ffc90
--- /dev/null
+++ b/lib/kofficeui/tkaction.h
@@ -0,0 +1,123 @@
+/*
+ * Kivio - Visual Modelling and Flowcharting
+ * Copyright (C) 2000 theKompany.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef TKACTION_H
+#define TKACTION_H
+
+#include <kaction.h>
+#include <qstringlist.h>
+#include <koffice_export.h>
+namespace TK {
+ enum IconMode { IconOnly, IconAndText, TextOnly };
+}
+
+class TKToolBarButton;
+class TKComboBox;
+
+class KOFFICEUI_EXPORT TKAction : public KAction
+{ Q_OBJECT
+public:
+ TKAction(QObject* parent, const char* name);
+ ~TKAction();
+
+ virtual int plug(QWidget* widget, int index = -1);
+
+ TK::IconMode iconMode();
+
+protected:
+ virtual void initToolBarButton(TKToolBarButton*);
+
+ QWidget* createLayout(QWidget* parent, QWidget* children);
+ void updateLayout();
+ virtual void updateLayout(QWidget*);
+
+public slots:
+ virtual void setIconMode(TK::IconMode);
+ void setText(const QString&);
+ void setIcon(const QString&);
+
+private:
+ TK::IconMode m_imode;
+ class TKActionPrivate;
+ TKActionPrivate *d;
+};
+/******************************************************************************/
+class KOFFICEUI_EXPORT TKBaseSelectAction : public TKAction
+{ Q_OBJECT
+friend class TKSelectAction;
+public:
+ TKBaseSelectAction(QObject* parent, const char* name);
+ ~TKBaseSelectAction();
+
+ virtual int plug(QWidget* widget, int index = -1);
+
+ int currentItem();
+ bool isEditable();
+
+ void activate(int);
+
+protected:
+ virtual void initComboBox(TKComboBox*);
+
+public slots:
+ virtual void setCurrentItem(int index);
+ virtual void setEditable(bool);
+
+protected slots:
+ virtual void slotActivated(int);
+
+signals:
+ void activated(int);
+
+private:
+ int m_current;
+ bool m_editable;
+ class TKBaseSelectActionPrivate;
+ TKBaseSelectActionPrivate *d;
+};
+/******************************************************************************/
+class KOFFICEUI_EXPORT TKSelectAction : public TKBaseSelectAction
+{ Q_OBJECT
+public:
+ TKSelectAction(QObject* parent, const char* name);
+ ~TKSelectAction();
+
+ QStringList items() const;
+
+public slots:
+ virtual void setItems(const QStringList& );
+ virtual void setEditText(const QString&);
+ virtual void clear();
+
+protected:
+ virtual void initComboBox(TKComboBox*);
+
+protected slots:
+ void slotActivated(const QString&);
+
+signals:
+ void activated(const QString&);
+
+private:
+ QStringList m_list;
+ class TKSelectActionPrivate;
+ TKSelectActionPrivate *d;
+};
+/******************************************************************************/
+#endif
diff --git a/lib/kofficeui/tkcoloractions.cpp b/lib/kofficeui/tkcoloractions.cpp
new file mode 100644
index 00000000..40859916
--- /dev/null
+++ b/lib/kofficeui/tkcoloractions.cpp
@@ -0,0 +1,621 @@
+/*
+ * Kivio - Visual Modelling and Flowcharting
+ * Copyright (C) 2000 theKompany.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#include "tkcoloractions.h"
+#include "tktoolbarbutton.h"
+
+#include <qlayout.h>
+#include <kcolordialog.h>
+#include <ktoolbar.h>
+#include <qpainter.h>
+#include <qtooltip.h>
+#include <qwhatsthis.h>
+#include <klocale.h>
+#include <kdebug.h>
+#include <qapplication.h>
+
+TKColorPopupMenu::TKColorPopupMenu( QWidget* parent, const char* name )
+: KPopupMenu(parent,name)
+{
+}
+
+TKColorPopupMenu::~TKColorPopupMenu()
+{
+}
+
+void TKColorPopupMenu::updateItemSize()
+{
+ styleChange(style());
+}
+/****************************************************************************************/
+class TKSelectColorActionPrivate
+{
+public:
+ TKSelectColorActionPrivate()
+ {
+ }
+ bool defaultColorMenu;
+ QColor defaultColor;
+};
+
+
+TKSelectColorAction::TKSelectColorAction( const QString& text, Type type, QObject* parent, const char* name, bool menuDefaultColor )
+: TKAction(parent,name)
+{
+ d=new TKSelectColorActionPrivate();
+ d->defaultColorMenu=menuDefaultColor;
+ d->defaultColor=QColor();
+ setText(text);
+ m_type = type;
+ init();
+}
+
+TKSelectColorAction::TKSelectColorAction( const QString& text, Type type,
+ QObject* receiver, const char* slot,
+ QObject* parent, const char* name, bool menuDefaultColor)
+: TKAction(parent,name)
+{
+ d=new TKSelectColorActionPrivate();
+ d->defaultColorMenu=menuDefaultColor;
+ d->defaultColor=QColor();
+ setText(text);
+ m_type = type;
+ connect( this, SIGNAL( activated() ), receiver, slot );
+ init();
+}
+
+void TKSelectColorAction::init()
+{
+ m_pStandardColor = new TKColorPanel();
+ m_pRecentColor = new TKColorPanel();
+
+ connect(m_pStandardColor,SIGNAL(colorSelected(const QColor&)),SLOT(panelColorSelected(const QColor&)));
+ connect(m_pStandardColor,SIGNAL(reject()),SLOT(panelReject()));
+ connect(m_pRecentColor,SIGNAL(colorSelected(const QColor&)),SLOT(panelColorSelected(const QColor&)));
+ connect(m_pRecentColor,SIGNAL(reject()),SLOT(panelReject()));
+
+ m_pRecentColor->clear();
+
+ m_pMenu = new TKColorPopupMenu();
+ m_pMenu->insertItem(m_pStandardColor);
+ m_pMenu->insertSeparator();
+ m_pMenu->insertItem(m_pRecentColor);
+ m_pMenu->insertSeparator();
+
+ switch (m_type) {
+ case TextColor:
+ m_pMenu->insertItem(i18n("More Text Colors..."),this,SLOT(selectColorDialog()));
+ setCurrentColor(black);
+ setIcon("textcolor");
+ break;
+ case LineColor:
+ m_pMenu->insertItem(i18n("More Line Colors..."),this,SLOT(selectColorDialog()));
+ setCurrentColor(black);
+ setIcon("color_line");
+ break;
+ case FillColor:
+ m_pMenu->insertItem(i18n("More Fill Colors..."),this,SLOT(selectColorDialog()));
+ setCurrentColor(white);
+ setIcon("color_fill");
+ break;
+ case Color:
+ break;
+ }
+ if(d->defaultColorMenu)
+ {
+ m_pMenu->insertSeparator();
+ m_pMenu->insertItem(i18n("Default Color"),this,SLOT(defaultColor()));
+ }
+
+ connect(m_pStandardColor,SIGNAL(sizeChanged()),m_pMenu,SLOT(updateItemSize()));
+ connect(m_pRecentColor,SIGNAL(sizeChanged()),m_pMenu,SLOT(updateItemSize()));
+}
+
+TKSelectColorAction::~TKSelectColorAction()
+{
+ delete m_pMenu;
+ delete d;
+}
+
+void TKSelectColorAction::initToolBarButton(TKToolBarButton* b)
+{
+ QWhatsThis::add( b, whatsThis() );
+ TKAction::initToolBarButton(b);
+ b->setDelayedPopup( popupMenu() );
+ updatePixmap(b);
+ updatePixmap();
+}
+
+void TKSelectColorAction::defaultColor()
+{
+ m_pCurrentColor = d->defaultColor;
+ emit activated();
+}
+
+void TKSelectColorAction::setDefaultColor(const QColor &_col)
+{
+ d->defaultColor=_col;
+}
+
+void TKSelectColorAction::updatePixmap()
+{
+ for( int id = 0; id < containerCount(); ++id ) {
+ QWidget* w = container(id);
+ if ( w->inherits("KToolBar") ) {
+ QWidget* r = static_cast<KToolBar*>(w)->getWidget(itemId(id));
+ if ( r->inherits("TKToolBarButton") ) {
+ updatePixmap(static_cast<TKToolBarButton*>(r));
+ }
+ }
+ else if(w->inherits("QPopupMenu") ) {
+ QPixmap pix =iconSet(KIcon::Small).pixmap(QIconSet::Automatic,QIconSet::Active);
+ if ( pix.isNull() )
+ return;
+ QPainter p(&pix);
+ switch (m_type) {
+ case TextColor:
+ p.fillRect(QRect(0,12,16,5), m_pCurrentColor);
+ break;
+ case LineColor:
+ p.fillRect(QRect(0,13,16,5), m_pCurrentColor);
+ p.fillRect(QRect(3,12,1,1), m_pCurrentColor);
+ break;
+ case FillColor:
+ p.fillRect(QRect(0,13,16,5), m_pCurrentColor);
+ p.fillRect(QRect(1,10,5,3), m_pCurrentColor);
+ break;
+ case Color:
+ break;
+ }
+ p.end();
+ setIconSet( pix );
+ }
+ }
+}
+
+void TKSelectColorAction::updatePixmap(TKToolBarButton* b)
+{
+ if (!b)
+ return;
+ // Not much point in painting with an invalid color
+ if (!m_pCurrentColor.isValid())
+ return;
+ QPixmap pix =b->getActivePixmap();
+ QPainter p(&pix);
+ switch (m_type) {
+ case TextColor:
+ p.fillRect(QRect(0,12,16,5), m_pCurrentColor);
+ break;
+ case LineColor:
+ p.fillRect(QRect(0,13,16,5), m_pCurrentColor);
+ p.fillRect(QRect(3,12,1,1), m_pCurrentColor);
+ break;
+ case FillColor:
+ p.fillRect(QRect(0,13,16,5), m_pCurrentColor);
+ p.fillRect(QRect(1,10,5,3), m_pCurrentColor);
+ break;
+ case Color:
+ break;
+ }
+ p.end();
+ b->setPixmap(pix);
+}
+
+void TKSelectColorAction::setCurrentColor( const QColor& color )
+{
+ if ( color == m_pCurrentColor )
+ return;
+ m_pCurrentColor = color;
+ setActiveColor( color );
+ m_pRecentColor->setActiveColor(color );
+ updatePixmap();
+}
+
+void TKSelectColorAction::setActiveColor( const QColor& color )
+{
+ m_pStandardColor->setActiveColor(color);
+}
+
+void TKSelectColorAction::selectColorDialog()
+{
+ QColor c = color();
+
+ if ( d->defaultColorMenu )
+ {
+ if ( KColorDialog::getColor(c,d->defaultColor, qApp->activeWindow()) == QDialog::Accepted )
+ {
+ setCurrentColor(c);
+ m_pRecentColor->insertColor(m_pCurrentColor);
+ activate();
+ }
+
+ }
+ else
+ {
+ if ( KColorDialog::getColor(c, qApp->activeWindow()) == QDialog::Accepted )
+ {
+ setCurrentColor(c);
+ m_pRecentColor->insertColor(m_pCurrentColor);
+ activate();
+ }
+ }
+}
+
+// Called when activating the menu item
+void TKSelectColorAction::slotActivated()
+{
+ //kdDebug() << "TKSelectColorAction::slotActivated" << endl;
+ selectColorDialog();
+}
+
+void TKSelectColorAction::activate()
+{
+ emit colorSelected(m_pCurrentColor);
+ emit activated();
+}
+
+void TKSelectColorAction::panelColorSelected( const QColor& color )
+{
+ m_pMenu->hide();
+ setCurrentColor(color);
+
+ activate();
+}
+
+void TKSelectColorAction::panelReject()
+{
+ m_pMenu->hide();
+}
+
+class TKColorPanel::TKColorPanelPrivate
+{
+public:
+ TKColorPanelPrivate()
+ {
+ panelCreated = false;
+ }
+
+ bool panelCreated;
+};
+
+/****************************************************************************************/
+TKColorPanel::TKColorPanel( QWidget* parent, const char* name )
+: QWidget(parent,name)
+{
+ d = new TKColorPanel::TKColorPanelPrivate();
+ m_activeColor = black;
+
+ //m_iX = 0; // happens in setNumCols() -> resetGrid()
+ //m_iY = 0; // anyway, so...
+
+ m_pLayout = 0L;
+ setNumCols(15);
+}
+
+void TKColorPanel::setNumCols( int col )
+{
+ m_iWidth = col;
+ resetGrid();
+
+ QDictIterator<TKColorPanelButton> it(m_pColorDict);
+ while ( it.current() ) {
+ addToGrid(it.current());
+ ++it;
+ }
+}
+
+TKColorPanel::~TKColorPanel()
+{
+ delete d;
+}
+
+void TKColorPanel::resetGrid()
+{
+ m_iX = 0;
+ m_iY = 0;
+
+ delete m_pLayout;
+ m_pLayout = new QGridLayout(this,0,m_iWidth+1,0,0);
+
+ emit sizeChanged();
+}
+
+void TKColorPanel::clear()
+{
+ m_pColorDict.setAutoDelete(true);
+ m_pColorDict.clear();
+ m_pColorDict.setAutoDelete(false);
+ d->panelCreated = true; // we don't want to create the default
+ // panel anymore now (b/c of recent colors)
+ resetGrid();
+}
+
+void TKColorPanel::insertColor( const QColor& color, const QString& text )
+{
+ if (m_pColorDict[color.name()])
+ return;
+
+ insertColor(color);
+ QToolTip::add(m_pColorDict[color.name()],text);
+}
+
+void TKColorPanel::insertColor( const QColor& color )
+{
+ if (m_pColorDict[color.name()])
+ return;
+
+ m_pLayout->setMargin(3);
+ TKColorPanelButton* f = new TKColorPanelButton(color,this);
+ m_pColorDict.insert(color.name(),f);
+ if ( m_activeColor == color )
+ f->setActive(true);
+
+ connect(f,SIGNAL(selected(const QColor&)),SLOT(selected(const QColor&)));
+
+ addToGrid(f);
+}
+
+void TKColorPanel::addToGrid( TKColorPanelButton* f )
+{
+ m_pLayout->addWidget(f,m_iY,m_iX);
+ f->show(); // yeehaaaw! ugly hack (Werner)
+ m_iX++;
+ if ( m_iX == m_iWidth ) {
+ m_iX = 0;
+ m_iY++;
+ }
+ emit sizeChanged();
+}
+
+void TKColorPanel::setActiveColor( const QColor& color )
+{
+ TKColorPanelButton* b = m_pColorDict[m_activeColor.name()];
+ if (b)
+ b->setActive(false);
+
+ m_activeColor = color;
+
+ b = m_pColorDict[m_activeColor.name()];
+ if (b)
+ b->setActive(true);
+}
+
+void TKColorPanel::mouseReleaseEvent( QMouseEvent* )
+{
+ reject();
+}
+
+void TKColorPanel::showEvent( QShowEvent *e )
+{
+ if ( !d->panelCreated )
+ fillPanel();
+ QWidget::showEvent(e);
+}
+
+void TKColorPanel::selected( const QColor& color )
+{
+ emit colorSelected(color);
+}
+
+void TKColorPanel::fillPanel()
+{
+ d->panelCreated = true;
+ blockSignals(true); // don't emit sizeChanged() all the time
+
+ // ### TODO: names without space (e.g. red) are lower case in rgb.txt
+ insertColor(QColor( 255, 0, 0 ), i18n( "color", "Red"));
+ insertColor(QColor( 255, 165, 0 ), i18n( "color", "Orange"));
+ insertColor(QColor( 255, 0, 255 ), i18n( "color", "Magenta"));
+ insertColor(QColor( 0, 0, 255 ), i18n( "color", "Blue"));
+ insertColor(QColor( 0, 255, 255 ), i18n( "color", "Cyan"));
+ insertColor(QColor( 0, 255, 0 ), i18n( "color", "Green"));
+ insertColor(QColor( 255, 255, 0 ), i18n( "color", "Yellow"));
+ insertColor(QColor( 165, 42, 42 ), i18n( "color", "Brown"));
+ insertColor(QColor( 139, 0, 0 ), i18n( "color", "DarkRed"));
+ insertColor(QColor( 255, 140, 0 ), i18n( "color", "DarkOrange"));
+ insertColor(QColor( 139, 0, 139 ), i18n( "color", "DarkMagenta"));
+ insertColor(QColor( 0, 0, 139 ), i18n( "color", "DarkBlue"));
+ insertColor(QColor( 0, 139, 139 ), i18n( "color", "DarkCyan"));
+ insertColor(QColor( 0, 100, 0 ), i18n( "color", "DarkGreen"));
+ insertColor(QColor( 130, 127, 0 ), i18n( "color", "DarkYellow")); // ### not in rgb.txt
+
+ insertColor(QColor( 255, 255, 255 ), i18n( "color", "White"));
+ insertColor(QColor( 229, 229, 229 ), i18n( "color", "Gray 90%")); // ### not in rgb.txt
+ insertColor(QColor( 204, 204, 204 ), i18n( "color", "Gray 80%")); // ### not in rgb.txt
+ insertColor(QColor( 178, 178, 178 ), i18n( "color", "Gray 70%")); // ### not in rgb.txt
+ insertColor(QColor( 153, 153, 153 ), i18n( "color", "Gray 60%")); // ### not in rgb.txt
+ insertColor(QColor( 127, 127, 127 ), i18n( "color", "Gray 50%")); // ### not in rgb.txt
+ insertColor(QColor( 102, 102, 102 ), i18n( "color", "Gray 40%")); // ### not in rgb.txt
+ insertColor(QColor( 76, 76, 76 ), i18n( "color", "Gray 30%")); // ### not in rgb.txt
+ insertColor(QColor( 51, 51, 51 ), i18n( "color", "Gray 20%")); // ### not in rgb.txt
+ insertColor(QColor( 25, 25, 25 ), i18n( "color", "Gray 10%")); // ### not in rgb.txt
+ insertColor(QColor( 0, 0, 0 ), i18n( "color", "Black"));
+
+ insertColor(QColor( 255, 255, 240 ), i18n( "color", "Ivory"));
+ insertColor(QColor( 255, 250, 250 ), i18n( "color", "Snow"));
+ insertColor(QColor( 245, 255, 250 ), i18n( "color", "MintCream"));
+ insertColor(QColor( 255, 250, 240 ), i18n( "color", "FloralWhite"));
+ insertColor(QColor( 255, 255, 224 ), i18n( "color", "LightYellow"));
+ insertColor(QColor( 240, 255, 255 ), i18n( "color", "Azure"));
+ insertColor(QColor( 248, 248, 255 ), i18n( "color", "GhostWhite"));
+ insertColor(QColor( 240, 255, 240 ), i18n( "color", "Honeydew"));
+ insertColor(QColor( 255, 245, 238 ), i18n( "color", "Seashell"));
+ insertColor(QColor( 240, 248, 255 ), i18n( "color", "AliceBlue"));
+ insertColor(QColor( 255, 248, 220 ), i18n( "color", "Cornsilk"));
+ insertColor(QColor( 255, 240, 245 ), i18n( "color", "LavenderBlush"));
+ insertColor(QColor( 253, 245, 230 ), i18n( "color", "OldLace"));
+ insertColor(QColor( 245, 245, 245 ), i18n( "color", "WhiteSmoke"));
+ insertColor(QColor( 255, 250, 205 ), i18n( "color", "LemonChiffon"));
+ insertColor(QColor( 224, 255, 255 ), i18n( "color", "LightCyan"));
+ insertColor(QColor( 250, 250, 210 ), i18n( "color", "LightGoldenrodYellow"));
+ insertColor(QColor( 250, 240, 230 ), i18n( "color", "Linen"));
+ insertColor(QColor( 245, 245, 220 ), i18n( "color", "Beige"));
+ insertColor(QColor( 255, 239, 213 ), i18n( "color", "PapayaWhip"));
+ insertColor(QColor( 255, 235, 205 ), i18n( "color", "BlanchedAlmond"));
+ insertColor(QColor( 250, 235, 215 ), i18n( "color", "AntiqueWhite"));
+ insertColor(QColor( 255, 228, 225 ), i18n( "color", "MistyRose"));
+ insertColor(QColor( 230, 230, 250 ), i18n( "color", "Lavender"));
+ insertColor(QColor( 255, 228, 196 ), i18n( "color", "Bisque"));
+ insertColor(QColor( 255, 228, 181 ), i18n( "color", "Moccasin"));
+ insertColor(QColor( 255, 222, 173 ), i18n( "color", "NavajoWhite"));
+ insertColor(QColor( 255, 218, 185 ), i18n( "color", "PeachPuff"));
+ insertColor(QColor( 238, 232, 170 ), i18n( "color", "PaleGoldenrod"));
+ insertColor(QColor( 245, 222, 179 ), i18n( "color", "Wheat"));
+ insertColor(QColor( 220, 220, 220 ), i18n( "color", "Gainsboro"));
+ insertColor(QColor( 240, 230, 140 ), i18n( "color", "Khaki"));
+ insertColor(QColor( 175, 238, 238 ), i18n( "color", "PaleTurquoise"));
+ insertColor(QColor( 255, 192, 203 ), i18n( "color", "Pink"));
+ insertColor(QColor( 238, 221, 130 ), i18n( "color", "LightGoldenrod"));
+ insertColor(QColor( 211, 211, 211 ), i18n( "color", "LightGray"));
+ insertColor(QColor( 255, 182, 193 ), i18n( "color", "LightPink"));
+ insertColor(QColor( 176, 224, 230 ), i18n( "color", "PowderBlue"));
+ insertColor(QColor( 127, 255, 212 ), i18n( "color", "Aquamarine"));
+ insertColor(QColor( 216, 191, 216 ), i18n( "color", "Thistle"));
+ insertColor(QColor( 173, 216, 230 ), i18n( "color", "LightBlue"));
+ insertColor(QColor( 152, 251, 152 ), i18n( "color", "PaleGreen"));
+ insertColor(QColor( 255, 215, 0 ), i18n( "color", "Gold"));
+ insertColor(QColor( 173, 255, 47 ), i18n( "color", "GreenYellow"));
+ insertColor(QColor( 176, 196, 222 ), i18n( "color", "LightSteelBlue"));
+ insertColor(QColor( 144, 238, 144 ), i18n( "color", "LightGreen"));
+ insertColor(QColor( 221, 160, 221 ), i18n( "color", "Plum"));
+ insertColor(QColor( 190, 190, 190 ), i18n( "color", "Gray"));
+ insertColor(QColor( 222, 184, 135 ), i18n( "color", "BurlyWood"));
+ insertColor(QColor( 135, 206, 250 ), i18n( "color", "LightSkyblue"));
+ insertColor(QColor( 255, 160, 122 ), i18n( "color", "LightSalmon"));
+ insertColor(QColor( 135, 206, 235 ), i18n( "color", "SkyBlue"));
+ insertColor(QColor( 210, 180, 140 ), i18n( "color", "Tan"));
+ insertColor(QColor( 238, 130, 238 ), i18n( "color", "Violet"));
+ insertColor(QColor( 244, 164, 96 ), i18n( "color", "SandyBrown"));
+ insertColor(QColor( 233, 150, 122 ), i18n( "color", "DarkSalmon"));
+ insertColor(QColor( 189, 183, 107 ), i18n( "color", "DarkKhaki"));
+ insertColor(QColor( 127, 255, 0 ), i18n( "color", "Chartreuse"));
+ insertColor(QColor( 169, 169, 169 ), i18n( "color", "DarkGray"));
+ insertColor(QColor( 124, 252, 0 ), i18n( "color", "LawnGreen"));
+ insertColor(QColor( 255, 105, 180 ), i18n( "color", "HotPink"));
+ insertColor(QColor( 250, 128, 114 ), i18n( "color", "Salmon"));
+ insertColor(QColor( 240, 128, 128 ), i18n( "color", "LightCoral"));
+ insertColor(QColor( 64, 224, 208 ), i18n( "color", "Turquoise"));
+ insertColor(QColor( 143, 188, 143 ), i18n( "color", "DarkSeagreen"));
+ insertColor(QColor( 218, 112, 214 ), i18n( "color", "Orchid"));
+ insertColor(QColor( 102, 205, 170 ), i18n( "color", "MediumAquamarine"));
+ insertColor(QColor( 255, 127, 80 ), i18n( "color", "Coral"));
+ insertColor(QColor( 154, 205, 50 ), i18n( "color", "YellowGreen"));
+ insertColor(QColor( 218, 165, 32 ), i18n( "color", "Goldenrod"));
+ insertColor(QColor( 72, 209, 204 ), i18n( "color", "MediumTurquoise"));
+ insertColor(QColor( 188, 143, 143 ), i18n( "color", "RosyBrown"));
+ insertColor(QColor( 219, 112, 147 ), i18n( "color", "PaleVioletRed"));
+ insertColor(QColor( 0, 250, 154 ), i18n( "color", "MediumSpringGreen"));
+ insertColor(QColor( 255, 99, 71 ), i18n( "color", "Tomato"));
+ insertColor(QColor( 0, 255, 127 ), i18n( "color", "SpringGreen"));
+ insertColor(QColor( 205, 133, 63 ), i18n( "color", "Peru"));
+ insertColor(QColor( 100, 149, 237 ), i18n( "color", "CornflowerBlue"));
+ insertColor(QColor( 132, 112, 255 ), i18n( "color", "LightSlateBlue"));
+ insertColor(QColor( 147, 112, 219 ), i18n( "color", "MediumPurple"));
+ insertColor(QColor( 186, 85, 211 ), i18n( "color", "MediumOrchid"));
+ insertColor(QColor( 95, 158, 160 ), i18n( "color", "CadetBlue"));
+ insertColor(QColor( 0, 206, 209 ), i18n( "color", "DarkTurquoise"));
+ insertColor(QColor( 0, 191, 255 ), i18n( "color", "DeepSkyblue"));
+ insertColor(QColor( 119, 136, 153 ), i18n( "color", "LightSlateGray"));
+ insertColor(QColor( 184, 134, 11 ), i18n( "color", "DarkGoldenrod"));
+ insertColor(QColor( 123, 104, 238 ), i18n( "color", "MediumSlateBlue"));
+ insertColor(QColor( 205, 92, 92 ), i18n( "color", "IndianRed"));
+ insertColor(QColor( 210, 105, 30 ), i18n( "color", "Chocolate"));
+ insertColor(QColor( 60, 179, 113 ), i18n( "color", "MediumSeaGreen"));
+ insertColor(QColor( 50, 205, 50 ), i18n( "color", "LimeGreen"));
+ insertColor(QColor( 32, 178, 170 ), i18n( "color", "LightSeaGreen"));
+ insertColor(QColor( 112, 128, 144 ), i18n( "color", "SlateGray"));
+ insertColor(QColor( 30, 144, 255 ), i18n( "color", "DodgerBlue"));
+ insertColor(QColor( 255, 69, 0 ), i18n( "color", "OrangeRed"));
+ insertColor(QColor( 255, 20, 147 ), i18n( "color", "DeepPink"));
+ insertColor(QColor( 70, 130, 180 ), i18n( "color", "SteelBlue"));
+ insertColor(QColor( 106, 90, 205 ), i18n( "color", "SlateBlue"));
+ insertColor(QColor( 107, 142, 35 ), i18n( "color", "OliveDrab"));
+ insertColor(QColor( 65, 105, 225 ), i18n( "color", "RoyalBlue"));
+ insertColor(QColor( 208, 32, 144 ), i18n( "color", "VioletRed"));
+ insertColor(QColor( 153, 50, 204 ), i18n( "color", "DarkOrchid"));
+ insertColor(QColor( 160, 32, 240 ), i18n( "color", "Purple"));
+ insertColor(QColor( 105, 105, 105 ), i18n( "color", "DimGray"));
+ insertColor(QColor( 138, 43, 226 ), i18n( "color", "BlueViolet"));
+ insertColor(QColor( 160, 82, 45 ), i18n( "color", "Sienna"));
+ insertColor(QColor( 199, 21, 133 ), i18n( "color", "MediumVioletRed"));
+ insertColor(QColor( 176, 48, 96 ), i18n( "color", "Maroon"));
+ insertColor(QColor( 46, 139, 87 ), i18n( "color", "SeaGreen"));
+ insertColor(QColor( 85, 107, 47 ), i18n( "color", "DarkOliveGreen"));
+ insertColor(QColor( 34, 139, 34 ), i18n( "color", "ForestGreen"));
+ insertColor(QColor( 139, 69, 19 ), i18n( "color", "SaddleBrown"));
+ insertColor(QColor( 148, 0, 211 ), i18n( "color", "DarkViolet"));
+ insertColor(QColor( 178, 34, 34 ), i18n( "color", "FireBrick"));
+ insertColor(QColor( 72, 61, 139 ), i18n( "color", "DarkSlateBlue"));
+ insertColor(QColor( 47, 79, 79 ), i18n( "color", "DarkSlateGray"));
+ insertColor(QColor( 25, 25, 112 ), i18n( "color", "MidnightBlue"));
+ insertColor(QColor( 0, 0, 205 ), i18n( "color", "MediumBlue"));
+ insertColor(QColor( 0, 0, 128 ), i18n( "color", "Navy"));
+
+ blockSignals(false); // Signals allowed again
+ emit sizeChanged(); // one call should be enough ;)
+}
+
+/****************************************************************************************/
+TKColorPanelButton::TKColorPanelButton( const QColor& color, QWidget* parent, const char* name )
+: QFrame(parent,name), m_Color(color), m_bActive(false)
+{
+ setFixedSize(16,16);
+ setFrameStyle( NoFrame );
+}
+
+TKColorPanelButton::~TKColorPanelButton()
+{
+}
+
+void TKColorPanelButton::enterEvent( QEvent* )
+{
+ if (!m_bActive)
+ setFrameStyle( Panel | Sunken );
+}
+
+void TKColorPanelButton::leaveEvent( QEvent* )
+{
+ if (!m_bActive)
+ setFrameStyle( NoFrame );
+}
+
+void TKColorPanelButton::paintEvent( QPaintEvent* ev )
+{
+ QFrame::paintEvent(ev);
+
+ QPainter p(this,this);
+ p.fillRect(2,2,12,12,m_Color);
+ p.setPen(gray);
+ p.drawRect(2,2,12,12);
+ p.end();
+}
+
+void TKColorPanelButton::setActive( bool f )
+{
+ m_bActive = f;
+ setFrameStyle( m_bActive ? Panel | Sunken : NoFrame );
+}
+
+void TKColorPanelButton::mouseReleaseEvent( QMouseEvent* )
+{
+ emit selected(m_Color);
+}
+#include "tkcoloractions.moc"
diff --git a/lib/kofficeui/tkcoloractions.h b/lib/kofficeui/tkcoloractions.h
new file mode 100644
index 00000000..0d8179a1
--- /dev/null
+++ b/lib/kofficeui/tkcoloractions.h
@@ -0,0 +1,169 @@
+/*
+ * Kivio - Visual Modelling and Flowcharting
+ * Copyright (C) 2000 theKompany.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef TKCOLORACTION_H
+#define TKCOLORACTION_H
+
+#include "tkaction.h"
+#include <koffice_export.h>
+#include <kpopupmenu.h>
+#include <qdict.h>
+
+class QGridLayout;
+class TKColorPanel;
+class TKSelectColorActionPrivate;
+
+class TKColorPopupMenu : public KPopupMenu
+{ Q_OBJECT
+public:
+ TKColorPopupMenu( QWidget* parent = 0, const char* name = 0 );
+ ~TKColorPopupMenu();
+
+public slots:
+ void updateItemSize();
+};
+/****************************************************************************************/
+class KOFFICEUI_EXPORT TKSelectColorAction : public TKAction
+{ Q_OBJECT
+public:
+ enum Type {
+ TextColor,
+ LineColor,
+ FillColor,
+ Color
+ };
+
+ TKSelectColorAction( const QString& text, Type type, QObject* parent, const char* name, bool menuDefaultColor=false);
+ TKSelectColorAction( const QString& text, Type type,
+ QObject* receiver, const char* slot,
+ QObject* parent, const char* name,bool menuDefaultColor=false );
+
+ virtual ~TKSelectColorAction();
+
+ QColor color() const { return m_pCurrentColor; }
+
+ KPopupMenu* popupMenu() const { return m_pMenu; }
+ void setDefaultColor(const QColor &_col);
+
+
+public slots:
+ void setCurrentColor( const QColor& );
+ void setActiveColor( const QColor& );
+ virtual void activate();
+
+signals:
+ void colorSelected( const QColor& );
+
+protected slots:
+ void selectColorDialog();
+ void panelColorSelected( const QColor& );
+ void panelReject();
+ virtual void slotActivated();
+ void defaultColor();
+
+protected:
+ void init();
+ virtual void initToolBarButton(TKToolBarButton*);
+ void updatePixmap();
+ void updatePixmap(TKToolBarButton*);
+
+protected:
+ TKColorPopupMenu* m_pMenu;
+ TKColorPanel* m_pStandardColor;
+ TKColorPanel* m_pRecentColor;
+ int m_type;
+
+ QColor m_pCurrentColor;
+
+private:
+ TKSelectColorActionPrivate *d;
+};
+/****************************************************************************************/
+class TKColorPanelButton : public QFrame
+{ Q_OBJECT
+public:
+ TKColorPanelButton( const QColor&, QWidget* parent, const char* name = 0 );
+ ~TKColorPanelButton();
+
+ void setActive( bool );
+
+ QColor panelColor() const { return m_Color; }
+
+signals:
+ void selected( const QColor& );
+
+protected:
+ virtual void paintEvent( QPaintEvent* );
+ virtual void enterEvent( QEvent* );
+ virtual void leaveEvent( QEvent* );
+ virtual void mouseReleaseEvent( QMouseEvent* );
+
+ QColor m_Color;
+ bool m_bActive;
+
+private:
+ class TKColorPanelButtonPrivate;
+ TKColorPanelButtonPrivate *d;
+};
+/****************************************************************************************/
+class TKColorPanel : public QWidget
+{ Q_OBJECT
+
+public:
+ TKColorPanel( QWidget* parent = 0L, const char* name = 0 );
+ ~TKColorPanel();
+
+ void setActiveColor( const QColor& );
+ void setNumCols( int col );
+ void clear();
+
+public slots:
+ void insertColor( const QColor& );
+ void insertColor( const QColor&, const QString& );
+ void selected( const QColor& );
+
+signals:
+ void colorSelected( const QColor& );
+ void reject();
+ void sizeChanged();
+
+protected:
+ void addToGrid( TKColorPanelButton* );
+ void resetGrid();
+
+ virtual void mouseReleaseEvent( QMouseEvent* );
+ virtual void showEvent( QShowEvent *e );
+
+ QGridLayout* m_pLayout;
+ int m_iWidth;
+ int m_iX;
+ int m_iY;
+
+ QColor m_activeColor;
+ QDict<TKColorPanelButton> m_pColorDict;
+
+private:
+ void fillPanel();
+
+ class TKColorPanelPrivate;
+ TKColorPanelPrivate *d;
+};
+
+#endif
diff --git a/lib/kofficeui/tkcombobox.cpp b/lib/kofficeui/tkcombobox.cpp
new file mode 100644
index 00000000..525afb44
--- /dev/null
+++ b/lib/kofficeui/tkcombobox.cpp
@@ -0,0 +1,123 @@
+/*
+ * Kivio - Visual Modelling and Flowcharting
+ * Copyright (C) 2000 theKompany.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+#include "tkcombobox.h"
+
+#include <qlistbox.h>
+#include <qpainter.h>
+#include <qstyle.h>
+#include <qdrawutil.h>
+
+#include <kapplication.h>
+
+TKComboBox::TKComboBox(QWidget* parent, const char* name)
+: QComboBox(false,parent,name)
+{
+}
+
+
+TKComboBox::TKComboBox( bool isEditable, QWidget* parent, const char* name )
+: QComboBox(isEditable,parent,name)
+{
+}
+
+TKComboBox::~TKComboBox()
+{
+}
+
+void TKComboBox::paintEvent(QPaintEvent*)
+{
+ QRect r;
+ if (editable()){
+#ifdef __GNUC__
+#warning "Left out for now, lacking a style expert (Werner)"
+#endif
+ //r = QRect( style().comboButtonRect( 0, 0, width(), height() ) );
+ r = QRect(4, 2, width()-height()-2, height()-4);
+ } else {
+ r = QRect(4, 2, width()-height()-2, height()-4);
+ }
+ int by = 2;
+ int bx = r.x() + r.width();
+ int bw = width() - bx - 2;
+ int bh = height()-4;
+
+ QPainter p( this );
+ const QColorGroup& g = colorGroup();
+
+ QRect fr(2,2,width()-4,height()-4);
+
+ if ( hasFocus()) {
+ p.fillRect( fr, g.brush( QColorGroup::Highlight ) );
+ } else {
+ p.fillRect( fr, g.brush( QColorGroup::Base ) );
+ }
+
+ QRect r1(1,1,width()-1,height()-1);
+ qDrawShadePanel( &p, r1, g, true, 1 );
+
+ static const char* arrow_down[] = {
+ "7 7 2 1",
+ "X c Gray0",
+ " c None",
+ "XXXXXXX",
+ "XXXXXXX",
+ " ",
+ "XXXXXXX",
+ " XXXXX ",
+ " XXX ",
+ " X "};
+
+ QPixmap pixmap(arrow_down);
+
+
+ style().drawControl( QStyle::CE_PushButton, &p, this, QRect( bx, by, bw, bh ), colorGroup() );
+ style().drawItem( &p, QRect( bx, by, bw, bh), AlignCenter, colorGroup(), isEnabled(), &pixmap, QString::null );
+
+ if ( hasFocus()) {
+ style().drawPrimitive( QStyle::PE_FocusRect, &p, fr, g );
+ }
+
+ if (!editable()) {
+ p.setClipRect(r);
+ p.setPen( g.text() );
+ p.setBackgroundColor( g.background() );
+
+ if ( listBox()->item(currentItem()) ) {
+ QListBoxItem * item = listBox()->item(currentItem());
+ const QPixmap *pix = item->pixmap();
+ QString text = item->text();
+ int x = r.x();
+ if ( pix ) {
+ p.drawPixmap( x, r.y() + ( r.height() - pix->height() ) / 2 +1, *pix );
+ x += pix->width()+3;
+ }
+ if (!text.isEmpty())
+ p.drawText( x, r.y(), r.width()-x, r.height(), AlignLeft|AlignVCenter|SingleLine, text );
+ }
+ }
+ p.end();
+}
+
+void TKComboBox::activate()
+{
+ emit activated(currentItem());
+}
+
+#include "tkcombobox.moc"
diff --git a/lib/kofficeui/tkcombobox.h b/lib/kofficeui/tkcombobox.h
new file mode 100644
index 00000000..8b036dd6
--- /dev/null
+++ b/lib/kofficeui/tkcombobox.h
@@ -0,0 +1,41 @@
+/*
+ * Kivio - Visual Modelling and Flowcharting
+ * Copyright (C) 2000 theKompany.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef TKCOMBOBOX_H
+#define TKCOMBOBOX_H
+
+#include <qcombobox.h>
+class TKComboBox : public QComboBox
+{ Q_OBJECT
+public:
+ TKComboBox(QWidget* parent=0, const char* name=0);
+ TKComboBox(bool isEditable, QWidget* parent=0, const char* name=0);
+ ~TKComboBox();
+
+ void activate();
+
+protected:
+ void paintEvent(QPaintEvent*);
+
+private:
+ class TKComboBoxPrivate;
+ TKComboBoxPrivate *d;
+};
+
+#endif
diff --git a/lib/kofficeui/tktoolbarbutton.cpp b/lib/kofficeui/tktoolbarbutton.cpp
new file mode 100644
index 00000000..b6baba1a
--- /dev/null
+++ b/lib/kofficeui/tktoolbarbutton.cpp
@@ -0,0 +1,532 @@
+/*
+ * Kivio - Visual Modelling and Flowcharting
+ * Copyright (C) 2000 theKompany.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+#include <tktoolbarbutton.h>
+
+#include <qtimer.h>
+#include <qtooltip.h>
+#include <qpopupmenu.h>
+#include <qcursor.h>
+#include <qpainter.h>
+#include <qdrawutil.h>
+#include <qstyle.h>
+
+#include <kdeversion.h>
+#include <kapplication.h>
+#include <kiconeffect.h>
+#include <kiconloader.h>
+#include <kglobalsettings.h>
+
+// Delay in ms before delayed popup pops up
+#define POPUP_DELAY 500
+
+class TKToolBarButton::TKToolBarButtonPrivate
+{
+public:
+ TKToolBarButtonPrivate()
+ {
+ m_iconMode = TK::IconOnly;
+ m_isPopup = false;
+ m_isToggle = false;
+ m_isOn = false;
+ m_isRaised = false;
+ m_autoRaised = true;
+ ignoreNextMousePress = false;
+
+ m_text = QString::null;
+ m_iconName = QString::null;
+ m_arrowPressed = false;
+ m_delayTimer = 0L;
+ m_popup = 0L;
+
+ m_disabledIconName = QString::null;
+ m_defaultIconName = QString::null;
+
+ m_instance = KGlobal::instance();
+ }
+
+ ~TKToolBarButtonPrivate()
+ {
+ delete m_delayTimer;
+ m_delayTimer = 0;
+ }
+
+ bool m_isPopup;
+ bool m_isToggle;
+ bool m_isOn;
+ bool m_isRaised;
+ bool m_autoRaised;
+ bool m_arrowPressed;
+ bool ignoreNextMousePress;
+
+ QString m_text;
+ QString m_iconName;
+ QString m_disabledIconName;
+ QString m_defaultIconName;
+
+ TK::IconMode m_iconMode;
+
+ QTimer *m_delayTimer;
+ QPopupMenu *m_popup;
+
+ KInstance *m_instance;
+};
+
+TKToolBarButton::TKToolBarButton( const QString& icon, const QString& txt,
+ QWidget* parent, const char* name,
+ KInstance *instance )
+: QToolButton(parent,name)
+{
+ d = new TKToolBarButtonPrivate;
+ d->m_text = txt;
+ d->m_instance = instance;
+
+ setFocusPolicy( NoFocus );
+
+ connect(this, SIGNAL(clicked()), SLOT(slotClicked()) );
+ connect(this, SIGNAL(pressed()), SLOT(slotPressed()) );
+ connect(this, SIGNAL(released()), SLOT(slotReleased()) );
+
+ installEventFilter(this);
+
+ setIcon(icon);
+ modeChange();
+}
+
+TKToolBarButton::TKToolBarButton( const QPixmap& pixmap, const QString& txt, QWidget* parent, const char* name )
+: QToolButton(parent,name )
+{
+ d = new TKToolBarButtonPrivate;
+ d->m_text = txt;
+
+ setFocusPolicy( NoFocus );
+
+ connect(this, SIGNAL(clicked()), SLOT(slotClicked()) );
+ connect(this, SIGNAL(pressed()), SLOT(slotPressed()) );
+ connect(this, SIGNAL(released()), SLOT(slotReleased()) );
+
+ installEventFilter(this);
+
+ setPixmap(pixmap);
+ modeChange();
+}
+
+TKToolBarButton::~TKToolBarButton()
+{
+ delete d;
+}
+
+QString TKToolBarButton::text()
+{
+ return d->m_text;
+}
+
+void TKToolBarButton::modeChange()
+{
+ QToolTip::add(this,d->m_text);
+
+ int border = 3;
+ int w = 2*border;
+ int h = 2*border;
+
+ if (pixmap()) {
+ w += pixmap()->width();
+ h = QMAX(h,pixmap()->height()+2*border);
+ if (d->m_iconMode == TK::IconAndText && !d->m_text.isEmpty())
+ w += border;
+ }
+
+ if ((d->m_iconMode==TK::IconAndText||d->m_iconMode==TK::TextOnly) && !d->m_text.isEmpty())
+ {
+ QFont tmp_font = KGlobalSettings::toolBarFont();
+ QFontMetrics fm(tmp_font);
+
+ h = QMAX(h,fm.lineSpacing()+2*border);
+ w += fm.width(d->m_text);
+ }
+
+ if (d->m_popup && !d->m_isToggle)
+ w += 11;
+
+ QSize size(w,h);
+ setMinimumSize(size);
+
+ updateGeometry();
+}
+
+void TKToolBarButton::setEnabled( bool enabled )
+{
+ if (isEnabled()==enabled)
+ return;
+
+ QToolButton::setPixmap( (enabled ? defaultPixmap : disabledPixmap) );
+ QToolButton::setEnabled( enabled );
+}
+
+void TKToolBarButton::setText( const QString& text)
+{
+ d->m_text = text;
+ repaint(false);
+}
+
+void TKToolBarButton::setIcon( const QString& icon )
+{
+ d->m_iconName = icon;
+ int iconSize = 16;
+
+ setPixmap( BarIcon(icon, iconSize, KIcon::ActiveState, d->m_instance), false );
+ setDisabledPixmap( BarIcon(icon, iconSize, KIcon::DisabledState, d->m_instance) );
+ setDefaultPixmap( BarIcon(icon, iconSize, KIcon::DefaultState, d->m_instance) );
+}
+
+void TKToolBarButton::setDisabledIcon( const QString &icon )
+{
+ d->m_disabledIconName = icon;
+ int iconSize = 16;
+ setDisabledPixmap( BarIcon(icon, iconSize, KIcon::DisabledState, d->m_instance) );
+}
+
+void TKToolBarButton::setDefaultIcon( const QString &icon )
+{
+ d->m_defaultIconName = icon;
+ int iconSize = 16;
+ setDefaultPixmap( BarIcon(icon, iconSize, KIcon::DefaultState, d->m_instance) );
+}
+
+QPixmap TKToolBarButton::getActivePixmap() const
+{
+ return activePixmap;
+}
+
+void TKToolBarButton::setPixmap( const QPixmap &pixmap )
+{
+ setPixmap( pixmap, true );
+}
+
+void TKToolBarButton::setPixmap( const QPixmap &pixmap, bool generate )
+{
+ activePixmap = pixmap;
+
+ if ( generate )
+ {
+ makeDefaultPixmap();
+ makeDisabledPixmap();
+ }
+ else
+ {
+ if (defaultPixmap.isNull())
+ defaultPixmap = activePixmap;
+ if (disabledPixmap.isNull())
+ disabledPixmap = activePixmap;
+ }
+
+ QToolButton::setPixmap( isEnabled() ? defaultPixmap : disabledPixmap );
+}
+
+void TKToolBarButton::setDefaultPixmap( const QPixmap &pixmap )
+{
+ defaultPixmap = pixmap;
+ QToolButton::setPixmap( isEnabled() ? defaultPixmap : disabledPixmap );
+}
+
+void TKToolBarButton::setDisabledPixmap( const QPixmap &pixmap )
+{
+ disabledPixmap = pixmap;
+ QToolButton::setPixmap( isEnabled() ? defaultPixmap : disabledPixmap );
+}
+
+void TKToolBarButton::setPopup(QPopupMenu *p)
+{
+ d->m_popup = p;
+ d->m_popup->setFont(KGlobalSettings::toolBarFont());
+ p->installEventFilter(this);
+
+ modeChange();
+}
+
+QPopupMenu *TKToolBarButton::popup()
+{
+ return d->m_popup;
+}
+
+void TKToolBarButton::setDelayedPopup (QPopupMenu *p, bool toggle )
+{
+ d->m_isPopup = true;
+ setToggle(toggle);
+
+ if (!d->m_delayTimer) {
+ d->m_delayTimer = new QTimer(this);
+ connect(d->m_delayTimer, SIGNAL(timeout()), this, SLOT(slotDelayTimeout()));
+ }
+
+ setPopup(p);
+}
+
+void TKToolBarButton::setRaised(bool f)
+{
+ d->m_isRaised = f;
+ repaint(false);
+}
+
+void TKToolBarButton::setAutoRaised(bool f)
+{
+ d->m_autoRaised = f;
+}
+
+void TKToolBarButton::leaveEvent(QEvent *)
+{
+ if (!d->m_isToggle && !(d->m_popup && d->m_popup->isVisible()) ) {
+ QToolButton::setPixmap(isEnabled() ? defaultPixmap : disabledPixmap);
+ if (d->m_autoRaised)
+ setRaised(false);
+ }
+}
+
+void TKToolBarButton::enterEvent(QEvent *)
+{
+ if (!d->m_isToggle) {
+ if (isEnabled()) {
+ QToolButton::setPixmap(activePixmap);
+ if (d->m_autoRaised)
+ setRaised(true);
+ } else {
+ QToolButton::setPixmap(disabledPixmap);
+ }
+ repaint(false);
+ }
+}
+
+bool TKToolBarButton::eventFilter(QObject *o, QEvent *ev)
+{
+ if ( o == this )
+ if (ev->type() == QEvent::MouseButtonPress && d->m_popup && d->m_isPopup ) {
+ if (!d->m_isToggle) {
+ d->m_arrowPressed = arrowPressed( mapFromGlobal(QCursor::pos()) );
+ } else {
+ d->m_delayTimer->start(POPUP_DELAY);
+ }
+ }
+
+ if ( o == d->m_popup) {
+ switch (ev->type())
+ {
+ case QEvent::Show:
+ on(true);
+ return false;
+ case QEvent::Hide:
+ on(false);
+ setDown(false);
+ if ( !geometry().contains(parentWidget()->mapFromGlobal(QCursor::pos())) )
+ leaveEvent(0L);
+ return false;
+ break;
+ case QEvent::MouseButtonPress: {
+ d->m_arrowPressed = arrowPressed( mapFromGlobal(QCursor::pos()) );
+ d->ignoreNextMousePress = d->m_arrowPressed;
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ return false;
+}
+
+void TKToolBarButton::drawButton( QPainter* p )
+{
+#define DRAW_PIXMAP_AND_TEXT \
+ int x = 3;\
+ if (pixmap()) {\
+ style().drawItem( p, QRect( x, 0, pixmap()->width(), height() ), AlignCenter, colorGroup(), isEnabled(), pixmap(), QString::null );\
+ if (d->m_iconMode==TK::IconAndText && !d->m_text.isEmpty()) {\
+ x += pixmap()->width() + 3;\
+ }\
+ }\
+ if ((d->m_iconMode==TK::IconAndText||d->m_iconMode==TK::TextOnly) && !d->m_text.isEmpty()) {\
+ QFontMetrics fm(KGlobalSettings::toolBarFont());\
+ style().drawItem( p, QRect( x, 0, fm.width(d->m_text), height() ), AlignCenter, colorGroup(), isEnabled(), 0, d->m_text );\
+ }
+
+ const char* arrow[] = {
+ "7 4 2 1",
+ "# c Black",
+ ". c None",
+ "#######",
+ ".#####.",
+ "..###..",
+ "...#..."};
+ QPixmap arrow_pix(arrow);
+ bool f = d->m_isOn || isDown();
+
+ if (d->m_popup && !d->m_isToggle)
+ {
+ if (d->m_isPopup)
+ {
+ QStyle::SFlags flags = QStyle::Style_Default;
+ if (isEnabled()) flags |= QStyle::Style_Enabled;
+ if (isOn()) flags |= QStyle::Style_On;
+ if (d->m_isRaised) flags |= QStyle::Style_Raised;
+ if (hasFocus()) flags |= QStyle::Style_HasFocus;
+
+ style().drawComplexControl( QStyle::CC_ToolButton, p, this, QRect( 0, 0, width()-12, height() ), colorGroup(), flags, QStyle::SC_ToolButton );
+ style().drawComplexControl( QStyle::CC_ToolButton, p, this, QRect( width()-13, 0, 13, height() ), colorGroup(), flags, QStyle::SC_ToolButton );
+ style().drawItem( p, QRect( width()-13, 0, 13, height() ), AlignCenter, colorGroup(), isEnabled(), &arrow_pix, QString::null );
+ if ( d->m_isRaised )
+ qDrawShadeLine( p, width()-12, 0, width()-12, height(), colorGroup(), true );
+ DRAW_PIXMAP_AND_TEXT
+ } else {
+ style().drawControl( QStyle::CE_PushButton, p, this, QRect( 0, 0, width(), height() ), isEnabled() ? colorGroup() : palette().disabled(), f );
+ DRAW_PIXMAP_AND_TEXT
+ int z = f ? 1:0;
+ p->drawPixmap(width()-11+z,(height()-4)/2+z ,arrow_pix);
+ }
+ } else {
+ style().drawControl( QStyle::CE_PushButton, p, this, QRect( 0, 0, width(), height() ), isEnabled() ? colorGroup() : palette().disabled(), f );
+ DRAW_PIXMAP_AND_TEXT
+ }
+}
+
+void TKToolBarButton::paletteChange(const QPalette &)
+{
+ makeDisabledPixmap();
+ if ( !isEnabled() )
+ QToolButton::setPixmap( disabledPixmap );
+ else
+ QToolButton::setPixmap( defaultPixmap );
+ repaint(false);
+}
+
+void TKToolBarButton::makeDefaultPixmap()
+{
+ if (activePixmap.isNull())
+ return;
+
+ KIconEffect effect;
+ defaultPixmap = effect.apply(activePixmap, KIcon::Toolbar, KIcon::DefaultState);
+}
+
+void TKToolBarButton::makeDisabledPixmap()
+{
+ if (activePixmap.isNull())
+ return;
+
+ KIconEffect effect;
+ disabledPixmap = effect.apply(activePixmap, KIcon::Toolbar, KIcon::DisabledState);
+}
+
+QSize TKToolBarButton::sizeHint() const
+{
+ return minimumSize();
+}
+
+QSize TKToolBarButton::minimumSizeHint() const
+{
+ return minimumSize();
+}
+
+void TKToolBarButton::showMenu()
+{
+ QPoint p ( mapToGlobal( QPoint( 0, 0 ) ) );
+ const int deskHeight = KGlobalSettings::desktopGeometry(this).height();
+ if ( p.y() + height() + d->m_popup->height() > deskHeight )
+ p.setY( p.y() - d->m_popup->height() );
+ else
+ p.setY( p.y() + height( ));
+
+ d->m_popup->popup(p);
+}
+
+void TKToolBarButton::slotDelayTimeout()
+{
+ d->m_delayTimer->stop();
+ showMenu();
+}
+
+void TKToolBarButton::slotClicked()
+{
+ if ( d->ignoreNextMousePress ) {
+ d->ignoreNextMousePress=false;
+ return;
+ }
+
+ if (d->m_popup && !d->m_isPopup)
+ showMenu();
+ else
+ emit buttonClicked();
+}
+
+void TKToolBarButton::slotPressed()
+{
+ if ( d->ignoreNextMousePress )
+ return;
+
+ if (d->m_popup) {
+ if (!d->m_isPopup || d->m_isPopup && d->m_arrowPressed)
+ showMenu();
+ }
+ else
+ emit buttonPressed();
+
+ d->ignoreNextMousePress = false;
+}
+
+void TKToolBarButton::slotReleased()
+{
+ if (d->m_popup && d->m_isPopup)
+ d->m_delayTimer->stop();
+
+ emit buttonReleased();
+}
+
+void TKToolBarButton::slotToggled()
+{
+ emit buttonToggled();
+}
+
+void TKToolBarButton::on(bool flag)
+{
+ d->m_isOn = flag;
+ repaint();
+}
+
+void TKToolBarButton::toggle()
+{
+ on(!d->m_isOn);
+}
+
+void TKToolBarButton::setToggle(bool flag)
+{
+ d->m_isToggle = flag;
+ if (flag == true)
+ connect(this, SIGNAL(toggled(bool)), this, SLOT(slotToggled()));
+ else
+ disconnect(this, SIGNAL(toggled(bool)), this, SLOT(slotToggled()));
+
+ modeChange();
+ repaint();
+}
+
+void TKToolBarButton::setIconMode( TK::IconMode m )
+{
+ d->m_iconMode = m;
+ modeChange();
+ repaint();
+}
+
+#include <tktoolbarbutton.moc>
diff --git a/lib/kofficeui/tktoolbarbutton.h b/lib/kofficeui/tktoolbarbutton.h
new file mode 100644
index 00000000..a4724672
--- /dev/null
+++ b/lib/kofficeui/tktoolbarbutton.h
@@ -0,0 +1,227 @@
+/*
+ * Kivio - Visual Modelling and Flowcharting
+ * Copyright (C) 2000 theKompany.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef TKTOOLBARBUTTON_H
+#define TKTOOLBARBUTTON_H
+
+#include <tkaction.h>
+
+#include <qpixmap.h>
+#include <qtoolbutton.h>
+#include <kglobal.h>
+
+class KToolBar;
+class KInstance;
+class QPopupMenu;
+class QPainter;
+
+class TKToolBarButton : public QToolButton
+{ Q_OBJECT
+public:
+ TKToolBarButton(const QString& icon, const QString& txt,
+ QWidget* parent = 0, const char *name=0L,
+ KInstance *_instance = KGlobal::instance());
+
+ TKToolBarButton(const QPixmap&, const QString&, QWidget* parent=0, const char* name=0);
+ ~TKToolBarButton();
+
+ void setIconMode(TK::IconMode);
+ void setRaised(bool);
+ void setAutoRaised(bool);
+
+ /**
+ * Enable/Disable this button
+ *
+ * @param enable Defaults to true
+ */
+ void setEnabled(bool enable = true);
+
+ /**
+ * Set the pixmap directly for this button. This pixmap should be
+ * the active one... the dimmed and disabled pixmaps are constructed
+ * based on this one. However, don't use this function unless you
+ * are positive that you don't want to use @ref setIcon.
+ *
+ * @param pixmap The active pixmap
+ */
+ virtual void setPixmap(const QPixmap &pixmap);
+
+ /**
+ * Set the pixmap directly for this button. This pixmap should be
+ * the active one.. however, the disabled and default pixmaps will
+ * only be constructed if @ref #generate is true. In any event,
+ * don't use this function unless you are positive that you don't
+ * want to use @ref setIcon.
+ *
+ * @param pixmap The active pixmap
+ * @param generate If true, then the other pixmaps will be
+ * automatically generated using configurable effects
+ */
+ virtual void setPixmap(const QPixmap &pixmap, bool generate);
+
+ /**
+ * Force the button to use this pixmap as the default one rather
+ * then generating it using effects.
+ *
+ * @param pixmap The pixmap to use as the default (normal) one
+ */
+ virtual void setDefaultPixmap(const QPixmap& pixmap);
+
+ /**
+ * Force the button to use this pixmap when disabled one rather then
+ * generating it using effects.
+ *
+ * @param pixmap The pixmap to use when disabled
+ */
+ virtual void setDisabledPixmap(const QPixmap& pixmap);
+
+ /**
+ * Set the text for this button. The text will be either used as a
+ * tooltip (IconOnly) or will be along side the icon
+ *
+ * @param text The button (or tooltip) text
+ */
+ virtual void setText(const QString &text);
+ QString text();
+
+ /**
+ * Set the icon for this button. This icon should be the active
+ * one... the dimmed and disabled icons are constructed based on
+ * this one. The actual pixmap will be loaded internally. This
+ * function is preferred over @ref setPixmap
+ *
+ * @param icon The name of the active pixmap
+ */
+ virtual void setIcon(const QString &icon);
+
+ /**
+ * Force the button to use this icon as the default one rather
+ * then generating it using effects.
+ *
+ * @param icon The icon to use as the default (normal) one
+ */
+ virtual void setDefaultIcon(const QString& icon);
+
+ /**
+ * Force the button to use this icon when disabled one rather then
+ * generating it using effects.
+ *
+ * @param icon The icon to use when disabled
+ */
+ virtual void setDisabledIcon(const QString& icon);
+
+ /**
+ * Turn this button on or off
+ *
+ * @param flag true or false
+ */
+ void on(bool flag = true);
+
+ /**
+ * Toggle this button
+ */
+ void toggle();
+
+ /**
+ * Turn this button into a toggle button or disable the toggle
+ * aspects of it. This does not toggle the button itself. Use @ref
+ * toggle for that.
+ *
+ * @param toggle true or false
+ */
+ void setToggle(bool toggle = true);
+
+ /**
+ * Return a pointer to this button's popup menu (if it exists)
+ */
+ QPopupMenu *popup();
+
+ /**
+ * Give this button a popup menu. There will not be a delay when
+ * you press the button. Use @ref setDelayedPopup if you want that
+ * behavior
+ *
+ * @param p The new popup menu
+ */
+ void setPopup (QPopupMenu *p);
+
+ /**
+ * Gives this button a delayed popup menu.
+ *
+ * This function allows you to add a delayed popup menu to the button.
+ * The popup menu is then only displayed when the button is pressed and
+ * held down for about half a second. You can also make the poup-menu
+ * "sticky", i.e. visible until a selection is made or the mouse is
+ * clikced elsewhere, by simply setting the second argument to true.
+ * This "sticky" button feature allows you to make a selection without
+ * having to press and hold down the mouse while making a selection.
+ *
+ * @param p the new popup menu
+ * @param toggle if true, makes the button "sticky" (toggled)
+ */
+ void setDelayedPopup(QPopupMenu *p, bool toggle = false);
+
+ QPixmap getActivePixmap() const;
+
+ virtual QSize sizeHint() const;
+ virtual QSize minimumSizeHint() const;
+
+signals:
+ void buttonClicked();
+ void buttonPressed();
+ void buttonReleased();
+ void buttonToggled();
+
+public slots:
+ void modeChange();
+
+protected:
+ void paletteChange(const QPalette &);
+ void leaveEvent(QEvent *e);
+ void enterEvent(QEvent *e);
+ void drawButton(QPainter *p);
+ bool eventFilter (QObject *o, QEvent *e);
+ void showMenu();
+
+ void makeDefaultPixmap();
+ void makeDisabledPixmap();
+ bool arrowPressed( const QPoint& pos ) {
+ int x = pos.x();
+ int y = pos.y();
+ return (x > width() - 12 && x <= width() && y > 0 && y < height());
+ }
+
+private:
+ QPixmap defaultPixmap;
+ QPixmap activePixmap;
+ QPixmap disabledPixmap;
+ virtual void setIcon(const QPixmap &p) { QButton::setIcon(p); }
+ class TKToolBarButtonPrivate;
+ TKToolBarButtonPrivate *d;
+
+
+protected slots:
+ void slotClicked();
+ void slotPressed();
+ void slotReleased();
+ void slotToggled();
+ void slotDelayTimeout();
+};
+
+#endif