summaryrefslogtreecommitdiffabout
path: root/microkde
authorzautrix <zautrix>2004-06-26 19:01:18 (UTC)
committer zautrix <zautrix>2004-06-26 19:01:18 (UTC)
commitb9aad1f15dc600e4dbe4c62d3fcced6363188ba3 (patch) (unidiff)
tree2c3d4004fb21c72cba65793859f9bcd8ffd3a49c /microkde
downloadkdepimpi-b9aad1f15dc600e4dbe4c62d3fcced6363188ba3.zip
kdepimpi-b9aad1f15dc600e4dbe4c62d3fcced6363188ba3.tar.gz
kdepimpi-b9aad1f15dc600e4dbe4c62d3fcced6363188ba3.tar.bz2
Initial revision
Diffstat (limited to 'microkde') (more/less context) (ignore whitespace changes)
-rw-r--r--microkde/KDGanttMinimizeSplitter.cpp1636
-rw-r--r--microkde/KDGanttMinimizeSplitter.h186
-rw-r--r--microkde/kapplication.cpp26
-rw-r--r--microkde/kapplication.h21
-rw-r--r--microkde/kaudioplayer.h10
-rw-r--r--microkde/kcalendarsystem.cpp52
-rw-r--r--microkde/kcalendarsystem.h297
-rw-r--r--microkde/kcalendarsystemgregorian.cpp359
-rw-r--r--microkde/kcalendarsystemgregorian.h90
-rw-r--r--microkde/kcolorbutton.cpp36
-rw-r--r--microkde/kcolorbutton.h26
-rw-r--r--microkde/kcolordialog.cpp92
-rw-r--r--microkde/kcolordialog.h25
-rw-r--r--microkde/kcombobox.h12
-rw-r--r--microkde/kconfig.cpp467
-rw-r--r--microkde/kconfig.h100
-rw-r--r--microkde/kconfigtest.cpp14
-rw-r--r--microkde/kdatepickernew.cpp485
-rw-r--r--microkde/kdatepickernew.h253
-rw-r--r--microkde/kdatetbl.cpp735
-rw-r--r--microkde/kdatetbl.h308
-rw-r--r--microkde/kdebug.h92
-rw-r--r--microkde/kdecore/kcatalogue.cpp131
-rw-r--r--microkde/kdecore/kcatalogue.h104
-rw-r--r--microkde/kdecore/kconfigbase.h102
-rw-r--r--microkde/kdecore/klibloader.cpp626
-rw-r--r--microkde/kdecore/klibloader.h405
-rw-r--r--microkde/kdecore/klocale.cpp881
-rw-r--r--microkde/kdecore/klocale.h110
-rw-r--r--microkde/kdecore/klocale_new.cpp2441
-rw-r--r--microkde/kdecore/klocale_new.h1224
-rw-r--r--microkde/kdecore/kmdcodec.cpp1127
-rw-r--r--microkde/kdecore/kmdcodec.h572
-rw-r--r--microkde/kdecore/ksharedptr.h171
-rw-r--r--microkde/kdecore/kshell.cpp386
-rw-r--r--microkde/kdecore/kshell.h143
-rw-r--r--microkde/kdecore/kshortcut.h846
-rw-r--r--microkde/kdecore/kstandarddirs.cpp1620
-rw-r--r--microkde/kdecore/kstandarddirs.h681
-rw-r--r--microkde/kdecore/kstringhandler.cpp650
-rw-r--r--microkde/kdecore/kstringhandler.h417
-rw-r--r--microkde/kdemacros.h105
-rw-r--r--microkde/kdeui/kaction.cpp1215
-rw-r--r--microkde/kdeui/kaction.h624
-rw-r--r--microkde/kdeui/kactionclasses.cpp2058
-rw-r--r--microkde/kdeui/kactionclasses.h1223
-rw-r--r--microkde/kdeui/kactioncollection.cpp839
-rw-r--r--microkde/kdeui/kactioncollection.h329
-rw-r--r--microkde/kdeui/kbuttonbox.cpp300
-rw-r--r--microkde/kdeui/kbuttonbox.h139
-rw-r--r--microkde/kdeui/kcmodule.cpp106
-rw-r--r--microkde/kdeui/kcmodule.h266
-rw-r--r--microkde/kdeui/kguiitem.cpp205
-rw-r--r--microkde/kdeui/kguiitem.h87
-rw-r--r--microkde/kdeui/kjanuswidget.cpp1176
-rw-r--r--microkde/kdeui/kjanuswidget.h565
-rw-r--r--microkde/kdeui/klistbox.cpp314
-rw-r--r--microkde/kdeui/klistbox.h141
-rw-r--r--microkde/kdeui/klistview.cpp2191
-rw-r--r--microkde/kdeui/klistview.h1033
-rw-r--r--microkde/kdeui/kmainwindow.cpp994
-rw-r--r--microkde/kdeui/kmainwindow.h776
-rw-r--r--microkde/kdeui/knuminput.cpp1095
-rw-r--r--microkde/kdeui/knuminput.h948
-rw-r--r--microkde/kdeui/knumvalidator.cpp372
-rw-r--r--microkde/kdeui/knumvalidator.h209
-rw-r--r--microkde/kdeui/kseparator.cpp121
-rw-r--r--microkde/kdeui/kseparator.h77
-rw-r--r--microkde/kdeui/ksqueezedtextlabel.cpp107
-rw-r--r--microkde/kdeui/ksqueezedtextlabel.h76
-rw-r--r--microkde/kdeui/kstdaction.cpp362
-rw-r--r--microkde/kdeui/kstdaction.h568
-rw-r--r--microkde/kdeui/ktoolbar.cpp2260
-rw-r--r--microkde/kdeui/ktoolbar.h1107
-rw-r--r--microkde/kdeui/ktoolbarbutton.cpp756
-rw-r--r--microkde/kdeui/ktoolbarbutton.h313
-rw-r--r--microkde/kdeui/ktoolbarhandler.cpp253
-rw-r--r--microkde/kdeui/ktoolbarhandler.h70
-rw-r--r--microkde/kdeui/kxmlguiclient.cpp958
-rw-r--r--microkde/kdeui/kxmlguiclient.h361
-rw-r--r--microkde/kdialog.cpp17
-rw-r--r--microkde/kdialog.h18
-rw-r--r--microkde/kdialogbase.cpp278
-rw-r--r--microkde/kdialogbase.h139
-rw-r--r--microkde/kdirwatch.h14
-rw-r--r--microkde/keditlistbox.cpp389
-rw-r--r--microkde/keditlistbox.h226
-rw-r--r--microkde/kemailsettings.cpp6
-rw-r--r--microkde/kemailsettings.h32
-rw-r--r--microkde/kfiledialog.cpp74
-rw-r--r--microkde/kfiledialog.h20
-rw-r--r--microkde/kfontdialog.cpp32
-rw-r--r--microkde/kfontdialog.h15
-rw-r--r--microkde/kglobal.cpp166
-rw-r--r--microkde/kglobal.h68
-rw-r--r--microkde/kglobalsettings.cpp41
-rw-r--r--microkde/kglobalsettings.h30
-rw-r--r--microkde/kiconloader.cpp140
-rw-r--r--microkde/kiconloader.h52
-rw-r--r--microkde/kio/job.h12
-rw-r--r--microkde/kio/kfile/kurlrequester.cpp406
-rw-r--r--microkde/kio/kfile/kurlrequester.h269
-rw-r--r--microkde/klineedit.h24
-rw-r--r--microkde/klineeditdlg.h34
-rw-r--r--microkde/kmessagebox.cpp90
-rw-r--r--microkde/kmessagebox.h47
-rw-r--r--microkde/knotifyclient.h14
-rw-r--r--microkde/kprinter.h8
-rw-r--r--microkde/kprocess.cpp19
-rw-r--r--microkde/kprocess.h22
-rw-r--r--microkde/kresources/configdialog.cpp137
-rw-r--r--microkde/kresources/configdialog.h60
-rw-r--r--microkde/kresources/configpage.cpp507
-rw-r--r--microkde/kresources/configpage.h103
-rw-r--r--microkde/kresources/configwidget.cpp45
-rw-r--r--microkde/kresources/configwidget.h59
-rw-r--r--microkde/kresources/factory.cpp216
-rw-r--r--microkde/kresources/factory.h113
-rw-r--r--microkde/kresources/kcmkresources.cpp89
-rw-r--r--microkde/kresources/kcmkresources.h54
-rw-r--r--microkde/kresources/manager.h332
-rw-r--r--microkde/kresources/managerimpl.cpp353
-rw-r--r--microkde/kresources/managerimpl.h113
-rw-r--r--microkde/kresources/resource.cpp185
-rw-r--r--microkde/kresources/resource.h401
-rw-r--r--microkde/kresources/resourceselectdialog.h12
-rw-r--r--microkde/kresources/selectdialog.cpp154
-rw-r--r--microkde/kresources/selectdialog.h92
-rw-r--r--microkde/krestrictedline.h13
-rw-r--r--microkde/krun.cpp6
-rw-r--r--microkde/krun.h13
-rw-r--r--microkde/ksimpleconfig.h12
-rw-r--r--microkde/kstandarddirs_old.cpp151
-rw-r--r--microkde/kstandarddirs_old.h35
-rw-r--r--microkde/kstaticdeleter.h35
-rw-r--r--microkde/ksystemtray.cpp11
-rw-r--r--microkde/ksystemtray.h14
-rw-r--r--microkde/ktempfile.cpp25
-rw-r--r--microkde/ktempfile.h20
-rw-r--r--microkde/ktextedit.cpp53
-rw-r--r--microkde/ktextedit.h22
-rw-r--r--microkde/kunload.h6
-rw-r--r--microkde/kurl.cpp1942
-rw-r--r--microkde/kurl.h853
-rw-r--r--microkde/kutils/kcmultidialog.cpp201
-rw-r--r--microkde/kutils/kcmultidialog.h147
-rw-r--r--microkde/microkde.pro170
-rw-r--r--microkde/microkde.pro.back80
-rw-r--r--microkde/microkdeE.pro166
-rw-r--r--microkde/ofileselector_p.cpp863
-rw-r--r--microkde/ofileselector_p.h258
-rw-r--r--microkde/ofontselector.cpp412
-rw-r--r--microkde/ofontselector.h96
-rw-r--r--microkde/qlayoutengine_p.h111
-rw-r--r--microkde/words.sort.txt549
155 files changed, 54649 insertions, 0 deletions
diff --git a/microkde/KDGanttMinimizeSplitter.cpp b/microkde/KDGanttMinimizeSplitter.cpp
new file mode 100644
index 0000000..60b8bc7
--- a/dev/null
+++ b/microkde/KDGanttMinimizeSplitter.cpp
@@ -0,0 +1,1636 @@
1/* -*- Mode: C++ -*-
2 $Id$
3*/
4
5/****************************************************************************
6 ** Copyright (C) 2002-2004 Klarälvdalens Datakonsult AB. All rights reserved.
7 **
8 ** This file is part of the KDGantt library.
9 **
10 ** This file may be distributed and/or modified under the terms of the
11 ** GNU General Public License version 2 as published by the Free Software
12 ** Foundation and appearing in the file LICENSE.GPL included in the
13 ** packaging of this file.
14 **
15 ** Licensees holding valid commercial KDGantt licenses may use this file in
16 ** accordance with the KDGantt Commercial License Agreement provided with
17 ** the Software.
18 **
19 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
20 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
21 **
22 ** See http://www.klaralvdalens-datakonsult.se/Public/products/ for
23 ** information about KDGantt Commercial License Agreements.
24 **
25 ** Contact info@klaralvdalens-datakonsult.se if any conditions of this
26 ** licensing are not clear to you.
27 **
28 ** As a special exception, permission is given to link this program
29 ** with any edition of Qt, and distribute the resulting executable,
30 ** without including the source code for Qt in the source distribution.
31 **
32 **********************************************************************/
33
34#include "KDGanttMinimizeSplitter.h"
35#ifndef QT_NO_SPLITTER___
36
37#include "qpainter.h"
38#include "qdrawutil.h"
39#include "qbitmap.h"
40#if QT_VERSION >= 300
41#include "qptrlist.h"
42#include "qmemarray.h"
43#else
44#include <qlist.h>
45#include <qarray.h>
46#define QPtrList QList
47#define QMemArray QArray
48#endif
49#include "qlayoutengine_p.h"
50#include "qobjectlist.h"
51#include "qstyle.h"
52#include "qapplication.h" //sendPostedEvents
53#include <qvaluelist.h>
54#include <qcursor.h>
55#ifndef KDGANTT_MASTER_CVS
56//#include "KDGanttMinimizeSplitter.moc"
57#endif
58
59
60
61#ifndef DOXYGEN_SKIP_INTERNAL
62
63#if QT_VERSION >= 232
64static int mouseOffset;
65static int opaqueOldPos = -1; //### there's only one mouse, but this is a bit risky
66
67
68KDGanttSplitterHandle::KDGanttSplitterHandle( Qt::Orientation o,
69 KDGanttMinimizeSplitter *parent, const char * name )
70 : QWidget( parent, name ), _activeButton( 0 ), _collapsed( false )
71{
72
73 if ( QApplication::desktop()->width() > 320 && QApplication::desktop()->width() < 650 ) {
74 mSizeHint = QSize(7,7);
75 mUseOffset = true;
76 } else {
77 mSizeHint = QSize(6,6);
78 mUseOffset = false;
79 }
80 s = parent;
81 setOrientation(o);
82 setMouseTracking( true );
83 //setMaximumHeight( 5 ); // test only
84}
85
86QSize KDGanttSplitterHandle::sizeHint() const
87{
88 return mSizeHint;
89}
90
91void KDGanttSplitterHandle::setOrientation( Qt::Orientation o )
92{
93 orient = o;
94#ifndef QT_NO_CURSOR
95 if ( o == KDGanttMinimizeSplitter::Horizontal )
96 setCursor( splitHCursor );
97 else
98 setCursor( splitVCursor );
99#endif
100}
101
102
103void KDGanttSplitterHandle::mouseMoveEvent( QMouseEvent *e )
104{
105 updateCursor( e->pos() );
106 if ( !(e->state()&LeftButton) )
107 return;
108
109 if ( _activeButton != 0)
110 return;
111
112 QCOORD pos = s->pick(parentWidget()->mapFromGlobal(e->globalPos()))
113 - mouseOffset;
114 if ( true /*opaque()*/ ) {
115 s->moveSplitter( pos, id() );
116 } else {
117 int min = pos; int max = pos;
118 s->getRange( id(), &min, &max );
119 s->setRubberband( QMAX( min, QMIN(max, pos )));
120 }
121 _collapsed = false;
122}
123
124void KDGanttSplitterHandle::mousePressEvent( QMouseEvent *e )
125{
126 if ( e->button() == LeftButton ) {
127 _activeButton = onButton( e->pos() );
128 mouseOffset = s->pick(e->pos());
129 if ( _activeButton != 0)
130 repaint();
131 updateCursor( e->pos() );
132 }
133}
134
135void KDGanttSplitterHandle::updateCursor( const QPoint& p)
136{
137 if ( onButton( p ) != 0 ) {
138 setCursor( arrowCursor );
139 }
140 else {
141 if ( orient == KDGanttMinimizeSplitter::Horizontal )
142 setCursor( splitHCursor );
143 else
144 setCursor( splitVCursor );
145 }
146}
147void KDGanttSplitterHandle::toggle()
148{
149 int pos;
150 int min, max;
151 if ( !_collapsed ) {
152 s->expandPos( id(), &min, &max );
153 if ( s->minimizeDirection() == KDGanttMinimizeSplitter::Left
154 || s->minimizeDirection() == KDGanttMinimizeSplitter::Up ) {
155 pos = min;
156 }
157 else {
158 pos = max;
159 }
160
161 _origPos = s->pick(mapToParent( QPoint( 0,0 ) ));
162 s->moveSplitter( pos, id() );
163 _collapsed = true;
164 }
165 else {
166 s->moveSplitter( _origPos, id() );
167 _collapsed = false;
168 }
169}
170
171void KDGanttSplitterHandle::mouseReleaseEvent( QMouseEvent *e )
172{
173 if ( _activeButton != 0 ) {
174 if ( onButton( e->pos() ) == _activeButton )
175 {
176 toggle();
177 }
178 _activeButton = 0;
179 updateCursor( e->pos() );
180 }
181 else {
182 if ( !opaque() && e->button() == LeftButton ) {
183 QCOORD pos = s->pick(parentWidget()->mapFromGlobal(e->globalPos()))
184 - mouseOffset;
185 s->setRubberband( -1 );
186 s->moveSplitter( pos, id() );
187 }
188 }
189 repaint();
190}
191
192int KDGanttSplitterHandle::onButton( const QPoint& p )
193{
194 QValueList<QPointArray> list = buttonRegions();
195 int index = 1;
196 int add = 12;
197 for( QValueList<QPointArray>::Iterator it = list.begin(); it != list.end(); ++it ) {
198 QRect rect = (*it).boundingRect();
199 rect.setLeft( rect.left()- add );
200 rect.setRight( rect.right() + add);
201 rect.setTop( rect.top()- add );
202 rect.setBottom( rect.bottom() + add);
203 if ( rect.contains( p ) ) {
204 return index;
205 }
206 index++;
207 }
208 return 0;
209}
210
211
212QValueList<QPointArray> KDGanttSplitterHandle::buttonRegions()
213{
214 QValueList<QPointArray> list;
215
216 int sw = 8;
217 int yyy = 1;
218 int xxx = 1;
219 int voffset[] = { (int) -sw*3, (int) sw*3 };
220 for ( int i = 0; i < 2; i++ ) {
221 QPointArray arr;
222 if ( !_collapsed && s->minimizeDirection() == KDGanttMinimizeSplitter::Right ||
223 _collapsed && s->minimizeDirection() == KDGanttMinimizeSplitter::Left) {
224 int mid = height()/2 + voffset[i];
225 arr.setPoints( 3,
226 1-xxx, mid - sw + 4,
227 sw-3-xxx, mid,
228 1-xxx, mid + sw -4);
229 }
230 else if ( !_collapsed && s->minimizeDirection() == KDGanttMinimizeSplitter::Left ||
231 _collapsed && s->minimizeDirection() == KDGanttMinimizeSplitter::Right ) {
232 int mid = height()/2 + voffset[i];
233 arr.setPoints( 3,
234 sw-4, mid - sw + 4,
235 0, mid,
236 sw-4, mid + sw - 4);
237 }
238 else if ( !_collapsed && s->minimizeDirection() == KDGanttMinimizeSplitter::Up ||
239 _collapsed && s->minimizeDirection() == KDGanttMinimizeSplitter::Down) {
240 int mid = width()/2 + voffset[i];
241 arr.setPoints( 3,
242 mid - sw + 4, sw-4,
243 mid, 0,
244 mid + sw - 4, sw-4 );
245 }
246 else if ( !_collapsed && s->minimizeDirection() == KDGanttMinimizeSplitter::Down ||
247 _collapsed && s->minimizeDirection() == KDGanttMinimizeSplitter::Up ) {
248 int mid = width()/2 + voffset[i];
249 arr.setPoints( 3,
250 mid - sw + 4, 1-yyy,
251 mid, sw-3-yyy,
252 mid + sw -4, 1-yyy);
253 }
254 list.append( arr );
255 }
256 return list;
257}
258
259void KDGanttSplitterHandle::paintEvent( QPaintEvent * )
260{
261 QPixmap buffer( size() );
262 QPainter p( &buffer );
263
264 //LR
265 // Draw the splitter rectangle
266 p.setBrush( colorGroup().background() );
267 p.setPen( colorGroup().foreground() );
268 //p.drawRect( rect() );
269 buffer.fill( colorGroup().background() );
270 //buffer.fill( backgroundColor() );
271 // parentWidget()->style().drawPrimitive( QStyle::PE_Panel, &p, rect(), parentWidget()->colorGroup());
272
273 int sw = 8; // Hardcoded, given I didn't use styles anymore, I didn't like to use their size
274
275 // arrow color
276 QColor col;
277 if ( _activeButton )
278 col = colorGroup().background().dark( 250 );
279 else
280 col = colorGroup().background().dark( 150 );
281 //QColor col = backgroundColor().dark( 130 );
282 p.setBrush( col );
283 p.setPen( col );
284
285 QValueList<QPointArray> list = buttonRegions();
286 int index = 1;
287 if ( mUseOffset )
288 p.translate( 0, 1 );
289 for ( QValueList<QPointArray>::Iterator it = list.begin(); it != list.end(); ++it ) {
290 if ( index == _activeButton ) {
291
292 /*
293 if ( ! _collapsed ) {
294 p.save();
295 // p.translate( parentWidget()->style().pixelMetric( QStyle::PM_ButtonShiftHorizontal ),
296 // parentWidget()->style().pixelMetric( QStyle::PM_ButtonShiftVertical ) );
297 p.translate( -1, 0 );
298 p.drawPolygon( *it, true );
299 p.restore(); } else
300 */
301 p.drawPolygon( *it, true );
302
303 }
304 else {
305 /*
306 if ( ! _collapsed ) {
307 p.save();
308 p.translate( -1, 0 );
309 p.drawPolygon( *it, true );
310 p.restore();
311 } else
312 */
313 p.drawPolygon( *it, true );
314
315 }
316 index++;
317 }
318
319 // Draw the lines between the arrows
320 if ( s->minimizeDirection() == KDGanttMinimizeSplitter::Left ||
321 s->minimizeDirection() == KDGanttMinimizeSplitter::Right ) {
322 int mid = height()/2;
323 p.drawLine ( 1, mid - sw, 1, mid + sw );
324 p.drawLine ( 3, mid - sw, 3, mid + sw );
325 }
326 else if ( s->minimizeDirection() == KDGanttMinimizeSplitter::Up ||
327 s->minimizeDirection() == KDGanttMinimizeSplitter::Down ) {
328 int mid = width()/2;
329 p.drawLine( mid -sw, 1, mid +sw, 1 );
330 p.drawLine( mid -sw, 3, mid +sw, 3 );
331 }
332 bitBlt( this, 0, 0, &buffer );
333
334}
335#endif
336
337class QSplitterLayoutStruct
338{
339public:
340 KDGanttMinimizeSplitter::ResizeMode mode;
341 QCOORD sizer;
342 bool isSplitter;
343 QWidget *wid;
344};
345
346class QSplitterData
347{
348public:
349 QSplitterData() : opaque( FALSE ), firstShow( TRUE ) {}
350
351 QPtrList<QSplitterLayoutStruct> list;
352 bool opaque;
353 bool firstShow;
354};
355
356void kdganttGeomCalc( QMemArray<QLayoutStruct> &chain, int start, int count, int pos,
357 int space, int spacer );
358#endif // DOXYGEN_SKIP_INTERNAL
359
360
361/*!
362 \class KDGanttMinimizeSplitter KDGanttMinimizeSplitter.h
363 \brief The KDGanttMinimizeSplitter class implements a splitter
364 widget with minimize buttons.
365
366 This class (and its documentation) is largely a copy of Qt's
367 QSplitter; the copying was necessary because QSplitter is not
368 extensible at all. QSplitter and its documentation are licensed
369 according to the GPL and the Qt Professional License (if you hold
370 such a license) and are (C) Trolltech AS.
371
372 A splitter lets the user control the size of child widgets by
373 dragging the boundary between the children. Any number of widgets
374 may be controlled.
375
376 To show a QListBox, a QListView and a QTextEdit side by side:
377
378 \code
379 KDGanttMinimizeSplitter *split = new KDGanttMinimizeSplitter( parent );
380 QListBox *lb = new QListBox( split );
381 QListView *lv = new QListView( split );
382 QTextEdit *ed = new QTextEdit( split );
383 \endcode
384
385 In KDGanttMinimizeSplitter, the boundary can be either horizontal or
386 vertical. The default is horizontal (the children are side by side)
387 but you can use setOrientation( QSplitter::Vertical ) to set it to
388 vertical.
389
390 Use setResizeMode() to specify
391 that a widget should keep its size when the splitter is resized.
392
393 Although KDGanttMinimizeSplitter normally resizes the children only
394 at the end of a resize operation, if you call setOpaqueResize( TRUE
395 ) the widgets are resized as often as possible.
396
397 The initial distribution of size between the widgets is determined
398 by the initial size of each widget. You can also use setSizes() to
399 set the sizes of all the widgets. The function sizes() returns the
400 sizes set by the user.
401
402 If you hide() a child, its space will be distributed among the other
403 children. It will be reinstated when you show() it again. It is also
404 possible to reorder the widgets within the splitter using
405 moveToFirst() and moveToLast().
406*/
407
408
409
410static QSize minSize( const QWidget* /*w*/ )
411{
412 return QSize(0,0);
413}
414
415// This is the original version of minSize
416static QSize minSizeHint( const QWidget* w )
417{
418 QSize min = w->minimumSize();
419 QSize s;
420 if ( min.height() <= 0 || min.width() <= 0 )
421 s = w->minimumSizeHint();
422 if ( min.height() > 0 )
423 s.setHeight( min.height() );
424 if ( min.width() > 0 )
425 s.setWidth( min.width() );
426 return s.expandedTo(QSize(0,0));
427}
428
429
430
431/*!
432 Constructs a horizontal splitter with the \a parent and \a
433 name arguments being passed on to the QFrame constructor.
434*/
435KDGanttMinimizeSplitter::KDGanttMinimizeSplitter( QWidget *parent, const char *name )
436 :QFrame(parent,name,WPaintUnclipped)
437{
438 mFirstHandle = 0;
439#if QT_VERSION >= 232
440 orient = Horizontal;
441 init();
442#endif
443}
444
445/*!
446 Constructs a splitter with orientation \a o with the \a parent
447 and \a name arguments being passed on to the QFrame constructor.
448*/
449KDGanttMinimizeSplitter::KDGanttMinimizeSplitter( Orientation o, QWidget *parent, const char *name )
450 :QFrame(parent,name,WPaintUnclipped)
451{
452 mFirstHandle = 0;
453#if QT_VERSION >= 232
454 orient = o;
455 init();
456#endif
457}
458
459/*!
460 Destroys the splitter and any children.
461*/
462KDGanttMinimizeSplitter::~KDGanttMinimizeSplitter()
463{
464#if QT_VERSION >= 232
465 data->list.setAutoDelete( TRUE );
466 delete data;
467#endif
468}
469
470
471#if QT_VERSION >= 232
472void KDGanttMinimizeSplitter::init()
473{
474 data = new QSplitterData;
475 if ( orient == Horizontal )
476 setSizePolicy( QSizePolicy(QSizePolicy::Expanding,QSizePolicy::Minimum) );
477 else
478 setSizePolicy( QSizePolicy(QSizePolicy::Minimum,QSizePolicy::Expanding) );
479}
480#endif
481
482
483
484/*!
485 \brief the orientation of the splitter
486
487 By default the orientation is horizontal (the widgets are side by side).
488 The possible orientations are Qt:Vertical and Qt::Horizontal (the default).
489*/
490void KDGanttMinimizeSplitter::setOrientation( Orientation o )
491{
492#if QT_VERSION >= 232
493 if ( orient == o )
494 return;
495 orient = o;
496
497 if ( orient == Horizontal )
498 setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Minimum ) );
499 else
500 setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Expanding ) );
501
502 QSplitterLayoutStruct *s = data->list.first();
503 while ( s ) {
504 if ( s->isSplitter )
505 ((KDGanttSplitterHandle*)s->wid)->setOrientation( o );
506 s = data->list.next(); // ### next at end of loop, no iterator
507 }
508 recalc( isVisible() );
509#endif
510}
511
512
513#if QT_VERSION >= 232
514/*!
515 \reimp
516*/
517void KDGanttMinimizeSplitter::resizeEvent( QResizeEvent * )
518{
519 doResize();
520}
521
522
523/*
524 Inserts the widget \a w at the end (or at the beginning if \a first
525 is TRUE) of the splitter's list of widgets.
526
527 It is the responsibility of the caller of this function to make sure
528 that \a w is not already in the splitter and to call recalcId if
529 needed. (If \a first is TRUE, then recalcId is very probably
530 needed.)
531*/
532QSplitterLayoutStruct *KDGanttMinimizeSplitter::addWidget( QWidget *w, bool first )
533{
534 QSplitterLayoutStruct *s;
535 KDGanttSplitterHandle *newHandle = 0;
536 if ( data->list.count() > 0 ) {
537 s = new QSplitterLayoutStruct;
538 s->mode = KeepSize;
539 QString tmp = "qt_splithandle_";
540 tmp += w->name();
541 newHandle = new KDGanttSplitterHandle( orientation(), this, tmp.latin1() );
542 if ( ! mFirstHandle )
543 mFirstHandle = newHandle;
544 s->wid = newHandle;
545 newHandle->setId(data->list.count());
546 s->isSplitter = TRUE;
547 s->sizer = pick( newHandle->sizeHint() );
548 if ( first )
549 data->list.insert( 0, s );
550 else
551 data->list.append( s );
552 }
553 s = new QSplitterLayoutStruct;
554 s->mode = Stretch;
555 s->wid = w;
556 if ( !testWState( WState_Resized ) && w->sizeHint().isValid() )
557 s->sizer = pick( w->sizeHint() );
558 else
559 s->sizer = pick( w->size() );
560 s->isSplitter = FALSE;
561 if ( first )
562 data->list.insert( 0, s );
563 else
564 data->list.append( s );
565 if ( newHandle && isVisible() )
566 newHandle->show(); //will trigger sending of post events
567 return s;
568}
569
570
571/*!
572 Tells the splitter that a child widget has been inserted or removed.
573 The event is passed in \a c.
574*/
575void KDGanttMinimizeSplitter::childEvent( QChildEvent *c )
576{
577 if ( c->type() == QEvent::ChildInserted ) {
578 if ( !c->child()->isWidgetType() )
579 return;
580
581 if ( ((QWidget*)c->child())->testWFlags( WType_TopLevel ) )
582 return;
583
584 QSplitterLayoutStruct *s = data->list.first();
585 while ( s ) {
586 if ( s->wid == c->child() )
587 return;
588 s = data->list.next();
589 }
590 addWidget( (QWidget*)c->child() );
591 recalc( isVisible() );
592
593 } else if ( c->type() == QEvent::ChildRemoved ) {
594 QSplitterLayoutStruct *p = 0;
595 if ( data->list.count() > 1 )
596 p = data->list.at(1); //remove handle _after_ first widget.
597 QSplitterLayoutStruct *s = data->list.first();
598 while ( s ) {
599 if ( s->wid == c->child() ) {
600 data->list.removeRef( s );
601 delete s;
602 if ( p && p->isSplitter ) {
603 data->list.removeRef( p );
604 delete p->wid; //will call childEvent
605 delete p;
606 }
607 recalcId();
608 doResize();
609 return;
610 }
611 p = s;
612 s = data->list.next();
613 }
614 }
615}
616
617
618/*!
619 Shows a rubber band at position \a p. If \a p is negative, the
620 rubber band is removed.
621*/
622void KDGanttMinimizeSplitter::setRubberband( int p )
623{
624 QPainter paint( this );
625 paint.setPen( gray );
626 paint.setBrush( gray );
627 paint.setRasterOp( XorROP );
628 QRect r = contentsRect();
629 const int rBord = 3; //Themable????
630#if QT_VERSION >= 300
631 int sw = style().pixelMetric(QStyle::PM_SplitterWidth, this);
632#else
633 int sw = style().splitterWidth();
634#endif
635 if ( orient == Horizontal ) {
636 if ( opaqueOldPos >= 0 )
637 paint.drawRect( opaqueOldPos + sw/2 - rBord , r.y(),
638 2*rBord, r.height() );
639 if ( p >= 0 )
640 paint.drawRect( p + sw/2 - rBord, r.y(), 2*rBord, r.height() );
641 } else {
642 if ( opaqueOldPos >= 0 )
643 paint.drawRect( r.x(), opaqueOldPos + sw/2 - rBord,
644 r.width(), 2*rBord );
645 if ( p >= 0 )
646 paint.drawRect( r.x(), p + sw/2 - rBord, r.width(), 2*rBord );
647 }
648 opaqueOldPos = p;
649}
650
651
652/*! \reimp */
653bool KDGanttMinimizeSplitter::event( QEvent *e )
654{
655 if ( e->type() == QEvent::LayoutHint || ( e->type() == QEvent::Show && data->firstShow ) ) {
656 recalc( isVisible() );
657 if ( e->type() == QEvent::Show )
658 data->firstShow = FALSE;
659 }
660 return QWidget::event( e );
661}
662
663
664/*!
665 \obsolete
666
667 Draws the splitter handle in the rectangle described by \a x, \a y,
668 \a w, \a h using painter \a p.
669 \sa QStyle::drawPrimitive()
670*/
671void KDGanttMinimizeSplitter::drawSplitter( QPainter *p,
672 QCOORD x, QCOORD y, QCOORD w, QCOORD h )
673{
674#if 0
675 // LR
676 style().drawPrimitive(QStyle::PE_Splitter, p, QRect(x, y, w, h), colorGroup(),
677 (orientation() == Qt::Horizontal ?
678 QStyle::Style_Horizontal : 0));
679#endif
680}
681
682
683/*!
684 Returns the id of the splitter to the right of or below the widget \a w,
685 or 0 if there is no such splitter
686 (i.e. it is either not in this KDGanttMinimizeSplitter or it is at the end).
687*/
688int KDGanttMinimizeSplitter::idAfter( QWidget* w ) const
689{
690 QSplitterLayoutStruct *s = data->list.first();
691 bool seen_w = FALSE;
692 while ( s ) {
693 if ( s->isSplitter && seen_w )
694 return data->list.at();
695 if ( !s->isSplitter && s->wid == w )
696 seen_w = TRUE;
697 s = data->list.next();
698 }
699 return 0;
700}
701
702
703/*!
704 Moves the left/top edge of the splitter handle with id \a id as
705 close as possible to position \a p, which is the distance from the
706 left (or top) edge of the widget.
707
708 For Arabic and Hebrew the layout is reversed, and using this
709 function to set the position of the splitter might lead to
710 unexpected results, since in Arabic and Hebrew the position of
711 splitter one is to the left of the position of splitter zero.
712
713 \sa idAfter()
714*/
715void KDGanttMinimizeSplitter::moveSplitter( QCOORD p, int id )
716{
717 p = adjustPos( p, id );
718 QSplitterLayoutStruct *s = data->list.at(id);
719 int oldP = orient == Horizontal ? s->wid->x() : s->wid->y();
720 bool upLeft;
721 if ( false && orient == Horizontal ) {
722 p += s->wid->width();
723 upLeft = p > oldP;
724 } else
725 upLeft = p < oldP;
726
727 moveAfter( p, id, upLeft );
728 moveBefore( p-1, id-1, upLeft );
729
730 storeSizes();
731}
732
733
734void KDGanttMinimizeSplitter::setG( QWidget *w, int p, int s, bool isSplitter )
735{
736 if ( orient == Horizontal ) {
737 if ( false && orient == Horizontal && !isSplitter )
738 p = contentsRect().width() - p - s;
739 w->setGeometry( p, contentsRect().y(), s, contentsRect().height() );
740 } else
741 w->setGeometry( contentsRect().x(), p, contentsRect().width(), s );
742}
743
744
745/*
746 Places the right/bottom edge of the widget at \a id at position \a pos.
747
748 \sa idAfter()
749*/
750void KDGanttMinimizeSplitter::moveBefore( int pos, int id, bool upLeft )
751{
752 if( id < 0 )
753 return;
754 QSplitterLayoutStruct *s = data->list.at(id);
755 if ( !s )
756 return;
757 QWidget *w = s->wid;
758 if ( w->isHidden() ) {
759 moveBefore( pos, id-1, upLeft );
760 } else if ( s->isSplitter ) {
761 int pos1, pos2;
762 int dd = s->sizer;
763 if( false && orient == Horizontal ) {
764 pos1 = pos;
765 pos2 = pos + dd;
766 } else {
767 pos2 = pos - dd;
768 pos1 = pos2 + 1;
769 }
770 if ( upLeft ) {
771 setG( w, pos1, dd, TRUE );
772 moveBefore( pos2, id-1, upLeft );
773 } else {
774 moveBefore( pos2, id-1, upLeft );
775 setG( w, pos1, dd, TRUE );
776 }
777 } else {
778 int dd, newLeft, nextPos;
779 if( false && orient == Horizontal ) {
780 dd = w->geometry().right() - pos;
781 dd = QMAX( pick(minSize(w)), QMIN(dd, pick(w->maximumSize())));
782 newLeft = pos+1;
783 nextPos = newLeft + dd;
784 } else {
785 dd = pos - pick( w->pos() ) + 1;
786 dd = QMAX( pick(minSize(w)), QMIN(dd, pick(w->maximumSize())));
787 newLeft = pos-dd+1;
788 nextPos = newLeft - 1;
789 }
790 setG( w, newLeft, dd, TRUE );
791 moveBefore( nextPos, id-1, upLeft );
792 }
793}
794
795
796/*
797 Places the left/top edge of the widget at \a id at position \a pos.
798
799 \sa idAfter()
800*/
801void KDGanttMinimizeSplitter::moveAfter( int pos, int id, bool upLeft )
802{
803 QSplitterLayoutStruct *s = id < int(data->list.count()) ?
804 data->list.at(id) : 0;
805 if ( !s )
806 return;
807 QWidget *w = s->wid;
808 if ( w->isHidden() ) {
809 moveAfter( pos, id+1, upLeft );
810 } else if ( pick( w->pos() ) == pos ) {
811 //No need to do anything if it's already there.
812 return;
813 } else if ( s->isSplitter ) {
814 int dd = s->sizer;
815 int pos1, pos2;
816 if( false && orient == Horizontal ) {
817 pos2 = pos - dd;
818 pos1 = pos2 + 1;
819 } else {
820 pos1 = pos;
821 pos2 = pos + dd;
822 }
823 if ( upLeft ) {
824 setG( w, pos1, dd, TRUE );
825 moveAfter( pos2, id+1, upLeft );
826 } else {
827 moveAfter( pos2, id+1, upLeft );
828 setG( w, pos1, dd, TRUE );
829 }
830 } else {
831 int left = pick( w->pos() );
832 int right, dd,/* newRight,*/ newLeft, nextPos;
833 if ( false && orient == Horizontal ) {
834 dd = pos - left + 1;
835 dd = QMAX( pick(minSize(w)), QMIN(dd, pick(w->maximumSize())));
836 newLeft = pos-dd+1;
837 nextPos = newLeft - 1;
838 } else {
839 right = pick( w->geometry().bottomRight() );
840 dd = right - pos + 1;
841 dd = QMAX( pick(minSize(w)), QMIN(dd, pick(w->maximumSize())));
842 /*newRight = pos+dd-1;*/
843 newLeft = pos;
844 nextPos = newLeft + dd;
845 }
846 setG( w, newLeft, dd, TRUE );
847 /*if( right != newRight )*/
848 moveAfter( nextPos, id+1, upLeft );
849 }
850}
851
852
853void KDGanttMinimizeSplitter::expandPos( int id, int* min, int* max )
854{
855 QSplitterLayoutStruct *s = data->list.at(id-1);
856 QWidget* w = s->wid;
857 *min = pick( w->mapToParent( QPoint(0,0) ) );
858
859 if ( (uint) id == data->list.count() ) {
860 pick( size() );
861 }
862 else {
863 QSplitterLayoutStruct *s = data->list.at(id+1);
864 QWidget* w = s->wid;
865 *max = pick( w->mapToParent( QPoint( w->width(), w->height() ) ) ) -8;
866 }
867}
868
869
870/*!
871 Returns the valid range of the splitter with id \a id in \a *min and \a *max.
872
873 \sa idAfter()
874*/
875
876void KDGanttMinimizeSplitter::getRange( int id, int *min, int *max )
877{
878 int minB = 0;//before
879 int maxB = 0;
880 int minA = 0;
881 int maxA = 0;//after
882 int n = data->list.count();
883 if ( id < 0 || id >= n )
884 return;
885 int i;
886 for ( i = 0; i < id; i++ ) {
887 QSplitterLayoutStruct *s = data->list.at(i);
888 if ( s->wid->isHidden() ) {
889 //ignore
890 } else if ( s->isSplitter ) {
891 minB += s->sizer;
892 maxB += s->sizer;
893 } else {
894 minB += pick( minSize(s->wid) );
895 maxB += pick( s->wid->maximumSize() );
896 }
897 }
898 for ( i = id; i < n; i++ ) {
899 QSplitterLayoutStruct *s = data->list.at(i);
900 if ( s->wid->isHidden() ) {
901 //ignore
902 } else if ( s->isSplitter ) {
903 minA += s->sizer;
904 maxA += s->sizer;
905 } else {
906 minA += pick( minSize(s->wid) );
907 maxA += pick( s->wid->maximumSize() );
908 }
909 }
910 QRect r = contentsRect();
911 if ( orient == Horizontal && false ) {
912#if QT_VERSION >= 300
913 int splitterWidth = style().pixelMetric(QStyle::PM_SplitterWidth, this);
914#else
915 int splitterWidth = style().splitterWidth();
916#endif
917
918 if ( min )
919 *min = pick(r.topRight()) - QMIN( maxB, pick(r.size())-minA ) - splitterWidth;
920 if ( max )
921 *max = pick(r.topRight()) - QMAX( minB, pick(r.size())-maxA ) - splitterWidth;
922 } else {
923 if ( min )
924 *min = pick(r.topLeft()) + QMAX( minB, pick(r.size())-maxA );
925 if ( max )
926 *max = pick(r.topLeft()) + QMIN( maxB, pick(r.size())-minA );
927 }
928}
929
930
931/*!
932 Returns the closest legal position to \a p of the splitter with id \a id.
933
934 \sa idAfter()
935*/
936
937int KDGanttMinimizeSplitter::adjustPos( int p, int id )
938{
939 int min = 0;
940 int max = 0;
941 getRange( id, &min, &max );
942 p = QMAX( min, QMIN( p, max ) );
943
944 return p;
945}
946
947
948void KDGanttMinimizeSplitter::doResize()
949{
950 QRect r = contentsRect();
951 int i;
952 int n = data->list.count();
953 QMemArray<QLayoutStruct> a( n );
954 for ( i = 0; i< n; i++ ) {
955 a[i].init();
956 QSplitterLayoutStruct *s = data->list.at(i);
957 if ( s->wid->isHidden() ) {
958 a[i].stretch = 0;
959 a[i].sizeHint = a[i].minimumSize = 0;
960 a[i].maximumSize = 0;
961 } else if ( s->isSplitter ) {
962 a[i].stretch = 0;
963 a[i].sizeHint = a[i].minimumSize = a[i].maximumSize = s->sizer;
964 a[i].empty = FALSE;
965 } else if ( s->mode == KeepSize ) {
966 a[i].stretch = 0;
967 a[i].minimumSize = pick( minSize(s->wid) );
968 a[i].sizeHint = s->sizer;
969 a[i].maximumSize = pick( s->wid->maximumSize() );
970 a[i].empty = FALSE;
971 } else if ( s->mode == FollowSizeHint ) {
972 a[i].stretch = 0;
973 a[i].minimumSize = a[i].sizeHint = pick( s->wid->sizeHint() );
974 a[i].maximumSize = pick( s->wid->maximumSize() );
975 a[i].empty = FALSE;
976 } else { //proportional
977 a[i].stretch = s->sizer;
978 a[i].maximumSize = pick( s->wid->maximumSize() );
979 a[i].sizeHint = a[i].minimumSize = pick( minSize(s->wid) );
980 a[i].empty = FALSE;
981 }
982 }
983
984 kdganttGeomCalc( a, 0, n, pick( r.topLeft() ), pick( r.size() ), 0 );
985
986 for ( i = 0; i< n; i++ ) {
987 QSplitterLayoutStruct *s = data->list.at(i);
988 setG( s->wid, a[i].pos, a[i].size );
989 }
990
991}
992
993
994void KDGanttMinimizeSplitter::recalc( bool update )
995{
996 int fi = 2*frameWidth();
997 int maxl = fi;
998 int minl = fi;
999 int maxt = QWIDGETSIZE_MAX;
1000 int mint = fi;
1001 int n = data->list.count();
1002 bool first = TRUE;
1003 /*
1004 The splitter before a hidden widget is always hidden.
1005 The splitter before the first visible widget is hidden.
1006 The splitter before any other visible widget is visible.
1007 */
1008 for ( int i = 0; i< n; i++ ) {
1009 QSplitterLayoutStruct *s = data->list.at(i);
1010 if ( !s->isSplitter ) {
1011 QSplitterLayoutStruct *p = (i > 0) ? p = data->list.at( i-1 ) : 0;
1012 if ( p && p->isSplitter )
1013 if ( first || s->wid->isHidden() )
1014 p->wid->hide(); //may trigger new recalc
1015 else
1016 p->wid->show(); //may trigger new recalc
1017 if ( !s->wid->isHidden() )
1018 first = FALSE;
1019 }
1020 }
1021
1022 bool empty=TRUE;
1023 for ( int j = 0; j< n; j++ ) {
1024 QSplitterLayoutStruct *s = data->list.at(j);
1025 if ( !s->wid->isHidden() ) {
1026 empty = FALSE;
1027 if ( s->isSplitter ) {
1028 minl += s->sizer;
1029 maxl += s->sizer;
1030 } else {
1031 QSize minS = minSize(s->wid);
1032 minl += pick( minS );
1033 maxl += pick( s->wid->maximumSize() );
1034 mint = QMAX( mint, trans( minS ));
1035 int tm = trans( s->wid->maximumSize() );
1036 if ( tm > 0 )
1037 maxt = QMIN( maxt, tm );
1038 }
1039 }
1040 }
1041 if ( empty ) {
1042 if ( parentWidget() != 0 && parentWidget()->inherits("KDGanttMinimizeSplitter") ) {
1043 // nested splitters; be nice
1044 maxl = maxt = 0;
1045 } else {
1046 // KDGanttMinimizeSplitter with no children yet
1047 maxl = QWIDGETSIZE_MAX;
1048 }
1049 } else {
1050 maxl = QMIN( maxl, QWIDGETSIZE_MAX );
1051 }
1052 if ( maxt < mint )
1053 maxt = mint;
1054
1055 if ( orient == Horizontal ) {
1056 setMaximumSize( maxl, maxt );
1057 setMinimumSize( minl, mint );
1058 } else {
1059 setMaximumSize( maxt, maxl );
1060 setMinimumSize( mint, minl );
1061 }
1062 if ( update )
1063 doResize();
1064}
1065
1066/*!
1067 Sets resize mode of \a w to \a mode.
1068
1069 \sa ResizeMode
1070*/
1071
1072void KDGanttMinimizeSplitter::setResizeMode( QWidget *w, ResizeMode mode )
1073{
1074 processChildEvents();
1075 QSplitterLayoutStruct *s = data->list.first();
1076 while ( s ) {
1077 if ( s->wid == w ) {
1078 s->mode = mode;
1079 return;
1080 }
1081 s = data->list.next();
1082 }
1083 s = addWidget( w, TRUE );
1084 s->mode = mode;
1085}
1086
1087
1088/*!
1089 Returns TRUE if opaque resize is on; otherwise returns FALSE.
1090
1091 \sa setOpaqueResize()
1092*/
1093
1094bool KDGanttMinimizeSplitter::opaqueResize() const
1095{
1096 return data->opaque;
1097}
1098
1099
1100/*!
1101 If \a on is TRUE then opaque resizing is turned on; otherwise
1102 opaque resizing is turned off.
1103 Opaque resizing is initially turned off.
1104
1105 \sa opaqueResize()
1106*/
1107
1108void KDGanttMinimizeSplitter::setOpaqueResize( bool on )
1109{
1110 data->opaque = on;
1111}
1112
1113
1114/*!
1115 Moves widget \a w to the leftmost/top position.
1116*/
1117
1118void KDGanttMinimizeSplitter::moveToFirst( QWidget *w )
1119{
1120 processChildEvents();
1121 bool found = FALSE;
1122 QSplitterLayoutStruct *s = data->list.first();
1123 while ( s ) {
1124 if ( s->wid == w ) {
1125 found = TRUE;
1126 QSplitterLayoutStruct *p = data->list.prev();
1127 if ( p ) { // not already at first place
1128 data->list.take(); //take p
1129 data->list.take(); // take s
1130 data->list.insert( 0, p );
1131 data->list.insert( 0, s );
1132 }
1133 break;
1134 }
1135 s = data->list.next();
1136 }
1137 if ( !found )
1138 addWidget( w, TRUE );
1139 recalcId();
1140}
1141
1142
1143/*!
1144 Moves widget \a w to the rightmost/bottom position.
1145*/
1146
1147void KDGanttMinimizeSplitter::moveToLast( QWidget *w )
1148{
1149 processChildEvents();
1150 bool found = FALSE;
1151 QSplitterLayoutStruct *s = data->list.first();
1152 while ( s ) {
1153 if ( s->wid == w ) {
1154 found = TRUE;
1155 data->list.take(); // take s
1156 QSplitterLayoutStruct *p = data->list.current();
1157 if ( p ) { // the splitter handle after s
1158 data->list.take(); //take p
1159 data->list.append( p );
1160 }
1161 data->list.append( s );
1162 break;
1163 }
1164 s = data->list.next();
1165 }
1166 if ( !found )
1167 addWidget( w);
1168 recalcId();
1169}
1170
1171
1172void KDGanttMinimizeSplitter::recalcId()
1173{
1174 int n = data->list.count();
1175 for ( int i = 0; i < n; i++ ) {
1176 QSplitterLayoutStruct *s = data->list.at(i);
1177 if ( s->isSplitter )
1178 ((KDGanttSplitterHandle*)s->wid)->setId(i);
1179 }
1180}
1181
1182
1183/*!\reimp
1184*/
1185QSize KDGanttMinimizeSplitter::sizeHint() const
1186{
1187 constPolish();
1188 int l = 0;
1189 int t = 0;
1190 if ( children() ) {
1191 const QObjectList * c = children();
1192 QObjectListIt it( *c );
1193 QObject * o;
1194
1195 while( (o=it.current()) != 0 ) {
1196 ++it;
1197 if ( o->isWidgetType() &&
1198 !((QWidget*)o)->isHidden() ) {
1199 QSize s = ((QWidget*)o)->sizeHint();
1200 if ( s.isValid() ) {
1201 l += pick( s );
1202 t = QMAX( t, trans( s ) );
1203 }
1204 }
1205 }
1206 }
1207 return orientation() == Horizontal ? QSize( l, t ) : QSize( t, l );
1208}
1209
1210
1211/*!
1212\reimp
1213*/
1214
1215QSize KDGanttMinimizeSplitter::minimumSizeHint() const
1216{
1217 constPolish();
1218 int l = 0;
1219 int t = 0;
1220 if ( children() ) {
1221 const QObjectList * c = children();
1222 QObjectListIt it( *c );
1223 QObject * o;
1224
1225 while( (o=it.current()) != 0 ) {
1226 ++it;
1227 if ( o->isWidgetType() &&
1228 !((QWidget*)o)->isHidden() ) {
1229 QSize s = minSizeHint((QWidget*)o);
1230 if ( s.isValid() ) {
1231 l += pick( s );
1232 t = QMAX( t, trans( s ) );
1233 }
1234 }
1235 }
1236 }
1237 return orientation() == Horizontal ? QSize( l, t ) : QSize( t, l );
1238}
1239
1240
1241/*
1242 Calculates stretch parameters from current sizes
1243*/
1244
1245void KDGanttMinimizeSplitter::storeSizes()
1246{
1247 QSplitterLayoutStruct *s = data->list.first();
1248 while ( s ) {
1249 if ( !s->isSplitter )
1250 s->sizer = pick( s->wid->size() );
1251 s = data->list.next();
1252 }
1253}
1254
1255
1256#if 0 // ### remove this code ASAP
1257
1258/*!
1259 Hides \a w if \a hide is TRUE and updates the splitter.
1260
1261 \warning Due to a limitation in the current implementation,
1262 calling QWidget::hide() will not work.
1263*/
1264
1265void KDGanttMinimizeSplitter::setHidden( QWidget *w, bool hide )
1266{
1267 if ( w == w1 ) {
1268 w1show = !hide;
1269 } else if ( w == w2 ) {
1270 w2show = !hide;
1271 } else {
1272#ifdef QT_CHECK_RANGE
1273 qWarning( "KDGanttMinimizeSplitter::setHidden(), unknown widget" );
1274#endif
1275 return;
1276 }
1277 if ( hide )
1278 w->hide();
1279 else
1280 w->show();
1281 recalc( TRUE );
1282}
1283
1284
1285/*!
1286 Returns the hidden status of \a w
1287*/
1288
1289bool KDGanttMinimizeSplitter::isHidden( QWidget *w ) const
1290{
1291 if ( w == w1 )
1292 return !w1show;
1293 else if ( w == w2 )
1294 return !w2show;
1295#ifdef QT_CHECK_RANGE
1296 else
1297 qWarning( "KDGanttMinimizeSplitter::isHidden(), unknown widget" );
1298#endif
1299 return FALSE;
1300}
1301#endif
1302
1303
1304/*!
1305 Returns a list of the size parameters of all the widgets in this
1306 splitter.
1307
1308 Giving the values to another splitter's setSizes() function will
1309 produce a splitter with the same layout as this one.
1310
1311 Note that if you want to iterate over the list, you should
1312 iterate over a copy, e.g.
1313 \code
1314 QValueList<int> list = mySplitter.sizes();
1315 QValueList<int>::Iterator it = list.begin();
1316 while( it != list.end() ) {
1317 myProcessing( *it );
1318 ++it;
1319 }
1320 \endcode
1321
1322 \sa setSizes()
1323*/
1324
1325QValueList<int> KDGanttMinimizeSplitter::sizes() const
1326{
1327 if ( !testWState(WState_Polished) ) {
1328 QWidget* that = (QWidget*) this;
1329 that->polish();
1330 }
1331 QValueList<int> list;
1332 QSplitterLayoutStruct *s = data->list.first();
1333 while ( s ) {
1334 if ( !s->isSplitter )
1335 list.append( s->sizer );
1336 s = data->list.next();
1337 }
1338 return list;
1339}
1340
1341
1342
1343/*!
1344 Sets the size parameters to the values given in \a list.
1345 If the splitter is horizontal, the values set the sizes from
1346 left to right. If it is vertical, the sizes are applied from
1347 top to bottom.
1348 Extra values in \a list are ignored.
1349
1350 If \a list contains too few values, the result is undefined
1351 but the program will still be well-behaved.
1352
1353 \sa sizes()
1354*/
1355
1356void KDGanttMinimizeSplitter::setSizes( QValueList<int> list )
1357{
1358 processChildEvents();
1359 QValueList<int>::Iterator it = list.begin();
1360 QSplitterLayoutStruct *s = data->list.first();
1361 while ( s && it != list.end() ) {
1362 if ( !s->isSplitter ) {
1363 s->sizer = *it;
1364 ++it;
1365 }
1366 s = data->list.next();
1367 }
1368 doResize();
1369}
1370
1371
1372/*!
1373 Gets all posted child events, ensuring that the internal state of
1374 the splitter is consistent.
1375*/
1376
1377void KDGanttMinimizeSplitter::processChildEvents()
1378{
1379 QApplication::sendPostedEvents( this, QEvent::ChildInserted );
1380}
1381
1382
1383/*!
1384 \reimp
1385*/
1386
1387void KDGanttMinimizeSplitter::styleChange( QStyle& old )
1388{
1389
1390#if QT_VERSION >= 300
1391 int sw = style().pixelMetric(QStyle::PM_SplitterWidth, this);
1392#else
1393 int sw = style().splitterWidth();
1394#endif
1395 QSplitterLayoutStruct *s = data->list.first();
1396 while ( s ) {
1397 if ( s->isSplitter )
1398 s->sizer = sw;
1399 s = data->list.next();
1400 }
1401 doResize();
1402 QFrame::styleChange( old );
1403}
1404
1405#endif
1406
1407/*!
1408 Specifies the direction of the minimize buttons.
1409 If the orientation of the splitter is horizontal then with
1410 KDGanttMinimizeSplitter::Left or KDGanttMinimizeSplitter::Right should be used,
1411 otherwise either KDGanttMinimizeSplitter::Up or KDGanttMinimizeSplitter::Down
1412 should be used.
1413*/
1414void KDGanttMinimizeSplitter::setMinimizeDirection( Direction direction )
1415{
1416 _direction = direction;
1417}
1418
1419/*!
1420 Returns the direction of the minimize buttons.
1421*/
1422KDGanttMinimizeSplitter::Direction KDGanttMinimizeSplitter::minimizeDirection() const
1423{
1424 return _direction;
1425}
1426
1427/*
1428 This is a copy of qGeomCalc() in qlayoutengine.cpp which
1429 unfortunately isn't exported.
1430*/
1431static inline int toFixed( int i ) { return i * 256; }
1432static inline int fRound( int i ) {
1433 return ( i % 256 < 128 ) ? i / 256 : 1 + i / 256;
1434}
1435void kdganttGeomCalc( QMemArray<QLayoutStruct> &chain, int start, int count, int pos,
1436 int space, int spacer )
1437{
1438 typedef int fixed;
1439 int cHint = 0;
1440 int cMin = 0;
1441 int cMax = 0;
1442 int sumStretch = 0;
1443 int spacerCount = 0;
1444
1445 bool wannaGrow = FALSE; // anyone who really wants to grow?
1446 // bool canShrink = FALSE; // anyone who could be persuaded to shrink?
1447
1448 int i;
1449 for ( i = start; i < start + count; i++ ) {
1450 chain[i].done = FALSE;
1451 cHint += chain[i].sizeHint;
1452 cMin += chain[i].minimumSize;
1453 cMax += chain[i].maximumSize;
1454 sumStretch += chain[i].stretch;
1455 if ( !chain[i].empty )
1456 spacerCount++;
1457 wannaGrow = wannaGrow || chain[i].expansive;
1458 }
1459
1460 int extraspace = 0;
1461 if ( spacerCount )
1462 spacerCount--; // only spacers between things
1463 if ( space < cMin + spacerCount * spacer ) {
1464 //qDebug("not enough space");
1465 for ( i = start; i < start+count; i++ ) {
1466 chain[i].size = chain[i].minimumSize;
1467 chain[i].done = TRUE;
1468 }
1469 } else if ( space < cHint + spacerCount*spacer ) {
1470 // Less space than sizeHint, but more than minimum.
1471 // Currently take space equally from each, like in Qt 2.x.
1472 // Commented-out lines will give more space to stretchier items.
1473 int n = count;
1474 int space_left = space - spacerCount*spacer;
1475 int overdraft = cHint - space_left;
1476 //first give to the fixed ones:
1477 for ( i = start; i < start+count; i++ ) {
1478 if ( !chain[i].done && chain[i].minimumSize >= chain[i].sizeHint) {
1479 chain[i].size = chain[i].sizeHint;
1480 chain[i].done = TRUE;
1481 space_left -= chain[i].sizeHint;
1482 // sumStretch -= chain[i].stretch;
1483 n--;
1484 }
1485 }
1486 bool finished = n == 0;
1487 while ( !finished ) {
1488 finished = TRUE;
1489 fixed fp_over = toFixed( overdraft );
1490 fixed fp_w = 0;
1491
1492 for ( i = start; i < start+count; i++ ) {
1493 if ( chain[i].done )
1494 continue;
1495 // if ( sumStretch <= 0 )
1496 fp_w += fp_over / n;
1497 // else
1498 // fp_w += (fp_over * chain[i].stretch) / sumStretch;
1499 int w = fRound( fp_w );
1500 chain[i].size = chain[i].sizeHint - w;
1501 fp_w -= toFixed( w ); //give the difference to the next
1502 if ( chain[i].size < chain[i].minimumSize ) {
1503 chain[i].done = TRUE;
1504 chain[i].size = chain[i].minimumSize;
1505 finished = FALSE;
1506 overdraft -= chain[i].sizeHint - chain[i].minimumSize;
1507 // sumStretch -= chain[i].stretch;
1508 n--;
1509 break;
1510 }
1511 }
1512 }
1513 } else { //extra space
1514 int n = count;
1515 int space_left = space - spacerCount*spacer;
1516 // first give to the fixed ones, and handle non-expansiveness
1517 for ( i = start; i < start + count; i++ ) {
1518 if ( !chain[i].done && (chain[i].maximumSize <= chain[i].sizeHint
1519 || wannaGrow && !chain[i].expansive) ) {
1520 chain[i].size = chain[i].sizeHint;
1521 chain[i].done = TRUE;
1522 space_left -= chain[i].sizeHint;
1523 sumStretch -= chain[i].stretch;
1524 n--;
1525 }
1526 }
1527 extraspace = space_left;
1528 /*
1529 Do a trial distribution and calculate how much it is off.
1530 If there are more deficit pixels than surplus pixels, give
1531 the minimum size items what they need, and repeat.
1532 Otherwise give to the maximum size items, and repeat.
1533
1534 I have a wonderful mathematical proof for the correctness
1535 of this principle, but unfortunately this comment is too
1536 small to contain it.
1537 */
1538 int surplus, deficit;
1539 do {
1540 surplus = deficit = 0;
1541 fixed fp_space = toFixed( space_left );
1542 fixed fp_w = 0;
1543 for ( i = start; i < start+count; i++ ) {
1544 if ( chain[i].done )
1545 continue;
1546 extraspace = 0;
1547 if ( sumStretch <= 0 )
1548 fp_w += fp_space / n;
1549 else
1550 fp_w += (fp_space * chain[i].stretch) / sumStretch;
1551 int w = fRound( fp_w );
1552 chain[i].size = w;
1553 fp_w -= toFixed( w ); // give the difference to the next
1554 if ( w < chain[i].sizeHint ) {
1555 deficit += chain[i].sizeHint - w;
1556 } else if ( w > chain[i].maximumSize ) {
1557 surplus += w - chain[i].maximumSize;
1558 }
1559 }
1560 if ( deficit > 0 && surplus <= deficit ) {
1561 // give to the ones that have too little
1562 for ( i = start; i < start+count; i++ ) {
1563 if ( !chain[i].done &&
1564 chain[i].size < chain[i].sizeHint ) {
1565 chain[i].size = chain[i].sizeHint;
1566 chain[i].done = TRUE;
1567 space_left -= chain[i].sizeHint;
1568 sumStretch -= chain[i].stretch;
1569 n--;
1570 }
1571 }
1572 }
1573 if ( surplus > 0 && surplus >= deficit ) {
1574 // take from the ones that have too much
1575 for ( i = start; i < start+count; i++ ) {
1576 if ( !chain[i].done &&
1577 chain[i].size > chain[i].maximumSize ) {
1578 chain[i].size = chain[i].maximumSize;
1579 chain[i].done = TRUE;
1580 space_left -= chain[i].maximumSize;
1581 sumStretch -= chain[i].stretch;
1582 n--;
1583 }
1584 }
1585 }
1586 } while ( n > 0 && surplus != deficit );
1587 if ( n == 0 )
1588 extraspace = space_left;
1589 }
1590
1591 // as a last resort, we distribute the unwanted space equally
1592 // among the spacers (counting the start and end of the chain).
1593
1594 //### should do a sub-pixel allocation of extra space
1595 int extra = extraspace / ( spacerCount + 2 );
1596 int p = pos + extra;
1597 for ( i = start; i < start+count; i++ ) {
1598 chain[i].pos = p;
1599 p = p + chain[i].size;
1600 if ( !chain[i].empty )
1601 p += spacer+extra;
1602 }
1603}
1604
1605#endif
1606
1607/*!
1608 \enum KDGanttMinimizeSplitter::Direction
1609
1610 The values of this enumeration describe into which direction the
1611 splitter will collapse its child widgets. By extension, it also
1612 specifies the orientation of the splitter; collapsing to the left or
1613 to the right results in a horizontal splitter, collapsing to the top
1614 or bottom in a vertical splitter.
1615*/
1616
1617/*!
1618 \fn Orientation KDGanttMinimizeSplitter::orientation() const
1619
1620 Returns the orientation of the splitter.
1621*/
1622
1623/*! \enum KDGanttMinimizeSplitter::ResizeMode
1624
1625 This enum type describes how KDGanttMinimizeSplitter will resize each of its child widgets. The currently defined values are:
1626
1627 Stretch: the widget will be resized when the splitter
1628 itself is resized.
1629
1630 KeepSize: KDGanttMinimizeSplitter will try to keep this widget's size
1631 unchanged.
1632
1633 FollowSizeHint: KDGanttMinimizeSplitter will resize the widget when the
1634 widget's size hint changes.
1635*/
1636
diff --git a/microkde/KDGanttMinimizeSplitter.h b/microkde/KDGanttMinimizeSplitter.h
new file mode 100644
index 0000000..75e0443
--- a/dev/null
+++ b/microkde/KDGanttMinimizeSplitter.h
@@ -0,0 +1,186 @@
1/* -*- Mode: C++ -*-
2 $Id$
3*/
4
5/****************************************************************************
6 ** Copyright (C) 2001-2004 Klarälvdalens Datakonsult AB. All rights reserved.
7 **
8 ** This file is part of the KDGantt library.
9 **
10 ** This file may be distributed and/or modified under the terms of the
11 ** GNU General Public License version 2 as published by the Free Software
12 ** Foundation and appearing in the file LICENSE.GPL included in the
13 ** packaging of this file.
14 **
15 ** Licensees holding valid commercial KDGantt licenses may use this file in
16 ** accordance with the KDGantt Commercial License Agreement provided with
17 ** the Software.
18 **
19 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
20 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
21 **
22 ** See http://www.klaralvdalens-datakonsult.se/Public/products/ for
23 ** information about KDGantt Commercial License Agreements.
24 **
25 ** Contact info@klaralvdalens-datakonsult.se if any conditions of this
26 ** licensing are not clear to you.
27 **
28 ** As a special exception, permission is given to link this program
29 ** with any edition of Qt, and distribute the resulting executable,
30 ** without including the source code for Qt in the source distribution.
31 **
32 **********************************************************************/
33
34#ifndef KDGANTTMINIMIZESPLITTER_H
35#define KDGANTTMINIMIZESPLITTER_H
36
37#ifndef QT_H
38#include "qframe.h"
39#include "qvaluelist.h"
40#endif // QT_H
41
42#ifndef QT_NO_SPLITTER___
43class QSplitterData;
44class QSplitterLayoutStruct;
45class KDGanttSplitterHandle;
46class KDGanttMinimizeSplitter : public QFrame
47{
48 Q_OBJECT
49 // Q_ENUMS( Direction )
50 // Q_PROPERTY( Orientation orientation READ orientation WRITE setOrientation )
51 // Q_PROPERTY( Direction minimizeDirection READ minimizeDirection WRITE setMinimizeDirection )
52
53public:
54 enum ResizeMode { Stretch, KeepSize, FollowSizeHint };
55 enum Direction { Left, Right, Up, Down };
56
57 KDGanttMinimizeSplitter( QWidget* parent=0, const char* name=0 );
58 KDGanttMinimizeSplitter( Orientation, QWidget* parent=0, const char* name=0 );
59 ~KDGanttMinimizeSplitter();
60
61 virtual void setOrientation( Orientation );
62 Orientation orientation() const { return orient; }
63
64 void setMinimizeDirection( Direction );
65 Direction minimizeDirection() const;
66
67#if QT_VERSION >= 232
68 virtual void setResizeMode( QWidget *w, ResizeMode );
69 virtual void setOpaqueResize( bool = TRUE );
70 bool opaqueResize() const;
71
72 void moveToFirst( QWidget * );
73 void moveToLast( QWidget * );
74
75 void refresh() { recalc( TRUE ); }
76 QSize sizeHint() const;
77 QSize minimumSizeHint() const;
78
79 QValueList<int> sizes() const;
80 void setSizes( QValueList<int> );
81 KDGanttSplitterHandle* firstHandle(){ return mFirstHandle;}
82 void expandPos( int id, int* min, int* max );
83protected:
84 void childEvent( QChildEvent * );
85
86 bool event( QEvent * );
87 void resizeEvent( QResizeEvent * );
88
89 int idAfter( QWidget* ) const;
90
91 void moveSplitter( QCOORD pos, int id );
92 virtual void drawSplitter( QPainter*, QCOORD x, QCOORD y,
93 QCOORD w, QCOORD h );
94 void styleChange( QStyle& );
95 int adjustPos( int , int );
96 virtual void setRubberband( int );
97 void getRange( int id, int*, int* );
98
99private:
100 void init();
101 void recalc( bool update = FALSE );
102 void doResize();
103 void storeSizes();
104 void processChildEvents();
105 QSplitterLayoutStruct *addWidget( QWidget*, bool first = FALSE );
106 void recalcId();
107 void moveBefore( int pos, int id, bool upLeft );
108 void moveAfter( int pos, int id, bool upLeft );
109 void setG( QWidget *w, int p, int s, bool isSplitter = FALSE );
110
111 QCOORD pick( const QPoint &p ) const
112 { return orient == Horizontal ? p.x() : p.y(); }
113 QCOORD pick( const QSize &s ) const
114 { return orient == Horizontal ? s.width() : s.height(); }
115
116 QCOORD trans( const QPoint &p ) const
117 { return orient == Vertical ? p.x() : p.y(); }
118 QCOORD trans( const QSize &s ) const
119 { return orient == Vertical ? s.width() : s.height(); }
120 KDGanttSplitterHandle* mFirstHandle;
121 QSplitterData *data;
122#endif
123
124private:
125 Orientation orient;
126 Direction _direction;
127#ifndef DOXYGEN_SKIP_INTERNAL
128 friend class KDGanttSplitterHandle;
129#endif
130 private:// Disabled copy constructor and operator=
131#if defined(Q_DISABLE_COPY)
132 KDGanttMinimizeSplitter( const KDGanttMinimizeSplitter & );
133 KDGanttMinimizeSplitter& operator=( const KDGanttMinimizeSplitter & );
134#endif
135};
136
137#ifndef DOXYGEN_SKIP_INTERNAL
138// This class was continued from a verbatim copy of the
139// QSplitterHandle pertaining to the Qt Enterprise License and the
140// GPL. It has only been renamed to KDGanttSplitterHandler in order to
141// avoid a symbol clash on some platforms.
142class KDGanttSplitterHandle : public QWidget
143{
144 Q_OBJECT
145#if QT_VERSION >= 232
146public:
147 KDGanttSplitterHandle( Qt::Orientation o,
148 KDGanttMinimizeSplitter *parent, const char* name=0 );
149 void setOrientation( Qt::Orientation o );
150 Qt::Orientation orientation() const { return orient; }
151
152 bool opaque() const { return s->opaqueResize(); }
153
154 QSize sizeHint() const;
155 void toggle();
156
157 int id() const { return myId; } // data->list.at(id())->wid == this
158 void setId( int i ) { myId = i; }
159
160protected:
161 QValueList<QPointArray> buttonRegions();
162 void paintEvent( QPaintEvent * );
163 void mouseMoveEvent( QMouseEvent * );
164 void mousePressEvent( QMouseEvent * );
165 void mouseReleaseEvent( QMouseEvent * );
166 int onButton( const QPoint& p );
167 void updateCursor( const QPoint& p );
168
169private:
170 QSize mSizeHint;
171 bool mUseOffset;
172 Qt::Orientation orient;
173 bool opaq;
174 int myId;
175
176 KDGanttMinimizeSplitter *s;
177 int _activeButton;
178 bool _collapsed;
179 int _origPos;
180#endif
181};
182#endif
183
184#endif // QT_NO_SPLITTER
185
186#endif // KDGANTTMINIMIZESPLITTER_H
diff --git a/microkde/kapplication.cpp b/microkde/kapplication.cpp
new file mode 100644
index 0000000..a1d00a8
--- a/dev/null
+++ b/microkde/kapplication.cpp
@@ -0,0 +1,26 @@
1#include <stdlib.h>
2
3#include "kapplication.h"
4
5int KApplication::random()
6{
7 return rand();
8}
9
10//US
11QString KApplication::randomString(int length)
12{
13 if (length <=0 ) return QString::null;
14
15 QString str;
16 while (length--)
17 {
18 int r=random() % 62;
19 r+=48;
20 if (r>57) r+=7;
21 if (r>90) r+=6;
22 str += char(r);
23 // so what if I work backwards?
24 }
25 return str;
26}
diff --git a/microkde/kapplication.h b/microkde/kapplication.h
new file mode 100644
index 0000000..47e64e7
--- a/dev/null
+++ b/microkde/kapplication.h
@@ -0,0 +1,21 @@
1#ifndef MINIKDE_KAPPLICATION_H
2#define MINIKDE_KAPPLICATION_H
3
4#include "qstring.h"
5
6class KApplication
7{
8 public:
9 static int random();
10
11//US
12 /**
13 * Generates a random string. It operates in the range [A-Za-z0-9]
14 * @param length Generate a string of this length.
15 * @return the random string
16 */
17 static QString randomString(int length);
18};
19
20
21#endif
diff --git a/microkde/kaudioplayer.h b/microkde/kaudioplayer.h
new file mode 100644
index 0000000..ff196cf
--- a/dev/null
+++ b/microkde/kaudioplayer.h
@@ -0,0 +1,10 @@
1#ifndef MICROKDE_KAUDIOPLAYER_H
2#define MICROKDE_KAUDIOPLAYER_H
3
4class KAudioPlayer
5{
6 public:
7 static void play( const QString & ) {}
8};
9
10#endif
diff --git a/microkde/kcalendarsystem.cpp b/microkde/kcalendarsystem.cpp
new file mode 100644
index 0000000..530010d
--- a/dev/null
+++ b/microkde/kcalendarsystem.cpp
@@ -0,0 +1,52 @@
1/*
2 Copyright (c) 2002 Carlos Moro <cfmoro@correo.uniovi.es>
3 Copyright (c) 2002 Hans Petter Bieker <bieker@kde.org>
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21// Gregorian calendar system implementation factory for creation of kde calendar
22// systems.
23// Also default gregorian and factory classes
24
25#include <kglobal.h>
26
27#include "kcalendarsystem.h"
28
29class KCalendarSystemPrivate
30{
31public:
32 const KLocale * locale;
33};
34
35KCalendarSystem::KCalendarSystem(const KLocale * locale)
36 : d(new KCalendarSystemPrivate)
37{
38 d->locale = locale;
39}
40
41KCalendarSystem::~KCalendarSystem()
42{
43 delete d;
44}
45
46const KLocale * KCalendarSystem::locale() const
47{
48 if ( d->locale )
49 return d->locale;
50
51 return KGlobal::locale();
52}
diff --git a/microkde/kcalendarsystem.h b/microkde/kcalendarsystem.h
new file mode 100644
index 0000000..37af33e
--- a/dev/null
+++ b/microkde/kcalendarsystem.h
@@ -0,0 +1,297 @@
1/*
2 Copyright (c) 2002 Carlos Moro <cfmoro@correo.uniovi.es>
3 Copyright (c) 2002-2003 Hans Petter Bieker <bieker@kde.org>
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21#ifndef KCALENDARSYSTEM_H
22#define KCALENDARSYSTEM_H
23
24#include <qdatetime.h>
25#include <qstring.h>
26
27class KLocale;
28
29class KCalendarSystemPrivate;
30
31/**
32 * CalendarSystem abstract class, default derived kde gregorian class and
33 * factory class. Provides support for different calendar types for kde
34 * calendar widget and related stuff.
35 *
36 * Derived classes must be created through KCalendarFactory class
37 *
38 * @author Carlos Moro <cfmoro@correo.uniovi.es>
39 * @licence GNU-GPL v.2
40 * @version $Id$
41 * @since 3.2
42 */
43class KCalendarSystem
44{
45public:
46 /**
47 * Constructor of abstract calendar class. This will be called by the derived classes.
48 *
49 * @param locale It will use this locale for translations, 0 means global.
50 */
51 KCalendarSystem(const KLocale * locale = 0);
52
53 /**
54 * Descructor.
55 */
56 virtual ~KCalendarSystem();
57
58 /**
59 * Gets specific calendar type year for a given gregorian date
60 *
61 * @param date gregorian date
62 * @return year
63 */
64 virtual int year (const QDate & date) const = 0;
65
66 /**
67 * Gets specific calendar type month for a given gregorian date
68 *
69 * @param date gregorian date
70 * @return month number
71 */
72 virtual int month (const QDate & date) const = 0;
73
74 /**
75 * Gets specific calendar type day number of month for a given date
76 *
77 * @param date gregorian date equivalent to the specific one
78 * @return day of the month
79 */
80 virtual int day (const QDate & date) const = 0;
81
82 /**
83 * Gets specific calendar type number of day of week number for a given
84 * date
85 *
86 * @param date gregorian date
87 * @return day of week
88 */
89 virtual int dayOfWeek (const QDate & date) const = 0;
90
91 /**
92 * Gets specific calendar type day number of year for a given date
93 *
94 * @param date gregorian date equivalent to the specific one
95 * @return day number
96 */
97 virtual int dayOfYear (const QDate & date) const = 0;
98
99 /**
100 * Changes the date's year, month and day. The range of the year, month
101 * and day depends on which calendar is being used.
102 *
103 * @param date Date to change
104 * @param y Year
105 * @param m Month number
106 * @param d Day of month
107 * @return TRUE if the date is valid; otherwise returns FALSE.
108 */
109 virtual bool setYMD(QDate & date, int y, int m, int d) const = 0;
110
111 /**
112 * Returns a QDate object containing a date nyears later.
113 *
114 * @param date The old date
115 * @param nyears The number of years to add
116 * @return The new date
117 */
118 virtual QDate addYears(const QDate & date, int nyears) const = 0;
119
120 /**
121 * Returns a QDate object containing a date nmonths later.
122 *
123 * @param date The old date
124 * @param nmonths The number of months to add
125 * @return The new date
126 */
127 virtual QDate addMonths(const QDate & date, int nmonths) const = 0;
128
129 /**
130 * Returns a QDate object containing a date ndays later.
131 *
132 * @param date The old date
133 * @param ndays The number of days to add
134 * @return The new date
135 */
136 virtual QDate addDays(const QDate & date, int ndays) const = 0;
137
138 /**
139 * Gets specific calendar type number of month for a given year
140 *
141 * @param date The date whose year to use
142 * @return The number of months in that year
143 */
144 virtual int monthsInYear (const QDate & date) const = 0;
145
146 /**
147 * Gets the number of days in date whose years specified.
148 *
149 * @param date Gregorian date equivalent to the specific one
150 * @return The number of days in year
151 */
152 virtual int daysInYear (const QDate & date) const = 0;
153
154 /**
155 * Gets specific calendar type number of days in month for a given date
156 *
157 * @param date gregorian date
158 * @return number of days for month in date
159 */
160 virtual int daysInMonth (const QDate & date) const = 0;
161
162 /**
163 * Gets the number of weeks in year
164 *
165 * @param year the year
166 * @return number of weeks in year
167 */
168 virtual int weeksInYear(int year) const = 0;
169
170 /**
171 * Gets specific calendar type week number for a given date
172 *
173 * @param date gregorian date
174 * @return week number
175 */
176 virtual int weekNumber(const QDate& date, int * yearNum = 0) const = 0;
177
178 /**
179 * Gets specific calendar type month name for a given month number
180 * If an invalid month is specified, QString::null is returned.
181 *
182 * @param month The month number
183 * @param shortName Specifies if the short month name should be used
184 * @return The name of the month
185 */
186 virtual QString monthName (int month, bool shortName = false) const = 0;
187
188 /**
189 * Gets specific calendar type month name for a given gregorian date
190 *
191 * @param date Gregorian date
192 * @param shortName Specifies if the short month name should be used
193 * @return The name of the month
194 */
195 virtual QString monthName (const QDate & date, bool shortName = false ) const = 0;
196
197 /**
198 * Returns a string containing the possessive form of the month name.
199 * ("of January", "of February", etc.)
200 * It's needed in long format dates in some languages.
201 * If an invalid month is specified, QString::null is returned.
202 *
203 * @param month The month number
204 * @param shortName Specifies if the short month name should be used
205 *
206 * @return The possessive form of the name of the month
207 */
208 virtual QString monthNamePossessive(int month, bool shortName = false) const = 0;
209
210 /**
211 * Returns a string containing the possessive form of the month name.
212 * ("of January", "of February", etc.)
213 * It's needed in long format dates in some languages.
214 *
215 * @param date Gregorian date
216 * @param shortName Specifies if the short month name should be used
217 *
218 * @return The possessive form of the name of the month
219 */
220 virtual QString monthNamePossessive(const QDate & date, bool shortName = false) const = 0;
221
222 /**
223 * Gets specific calendar type week day name
224 * If an invalid week day is specified, QString::null is returned.
225 *
226 * @param weekDay number of day in week (1 -> Monday)
227 * @param shortName short or complete day name
228 * @return day name
229 */
230 virtual QString weekDayName (int weekDay, bool shortName = false) const = 0;
231
232 /**
233 * Gets specific calendar type week day name
234 *
235 * @param date the date
236 * @param shortName short or complete day name
237 * @return day name
238 */
239 virtual QString weekDayName (const QDate & date, bool shortName = false) const = 0;
240
241 /**
242 * Gets the first year value supported by specific calendar type
243 * algorithms.
244 *
245 * @return first year supported
246 */
247 virtual int minValidYear () const = 0;
248
249 /**
250 * Gets the maximum year value supported by specific calendar type
251 * algorithms (QDate, 8000)
252 *
253 * @return maximum year supported
254 */
255 virtual int maxValidYear () const = 0;
256
257 /**
258 * Gets the day of the week traditionaly associated with pray
259 *
260 * @return day number
261 */
262 virtual int weekDayOfPray () const = 0;
263
264 /**
265 * Gets the string representing the calendar
266 */
267 virtual QString calendarName() const = 0;
268
269 /**
270 * Gets if the calendar is lunar based
271 *
272 * @return if the calendar is lunar based
273 */
274 virtual bool isLunar() const = 0;
275
276 /**
277 * Gets if the calendar is lunisolar based
278 *
279 * @return if the calendar is lunisolar based
280 */
281 virtual bool isLunisolar() const = 0;
282
283 /**
284 * Gets if the calendar is solar based
285 *
286 * @return if the calendar is solar based
287 */
288 virtual bool isSolar() const = 0;
289
290protected:
291 const KLocale * locale() const;
292
293private:
294 KCalendarSystemPrivate * d;
295};
296
297#endif
diff --git a/microkde/kcalendarsystemgregorian.cpp b/microkde/kcalendarsystemgregorian.cpp
new file mode 100644
index 0000000..7c5b62a
--- a/dev/null
+++ b/microkde/kcalendarsystemgregorian.cpp
@@ -0,0 +1,359 @@
1/*
2 Copyright (c) 2002 Carlos Moro <cfmoro@correo.uniovi.es>
3 Copyright (c) 2002 Hans Petter Bieker <bieker@kde.org>
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21// Derived gregorian kde calendar class
22// Just a schema.
23
24#include <qdatetime.h>
25#include <qstring.h>
26
27#include <klocale.h>
28#include <kdebug.h>
29
30#include "kcalendarsystemgregorian.h"
31
32KCalendarSystemGregorian::KCalendarSystemGregorian(const KLocale * locale)
33 : KCalendarSystem(locale)
34{
35 kdDebug(5400) << "Created gregorian calendar" << endl;
36}
37
38KCalendarSystemGregorian::~KCalendarSystemGregorian()
39{
40}
41
42int KCalendarSystemGregorian::year(const QDate& date) const
43{
44// kdDebug(5400) << "Gregorian year..." << endl;
45 return date.year();
46}
47
48int KCalendarSystemGregorian::monthsInYear( const QDate & ) const
49{
50// kdDebug(5400) << "Gregorian monthsInYear" << endl;
51
52 return 12;
53}
54
55int KCalendarSystemGregorian::weeksInYear(int year) const
56{
57#if QT_VERSION >= 300
58 QDate temp;
59 temp.setYMD(year, 12, 31);
60
61 // If the last day of the year is in the first week, we have to check the
62 // week before
63 if ( temp.weekNumber() == 1 )
64 temp.addDays(-7);
65
66 return temp.weekNumber();
67#else
68 return 52;
69#endif
70}
71
72int KCalendarSystemGregorian::weekNumber(const QDate& date,
73 int * yearNum) const
74{
75#if QT_VERSION >= 300
76 return date.weekNumber(yearNum);
77#else
78 return 1;
79#endif
80}
81
82QString KCalendarSystemGregorian::monthName(const QDate& date,
83 bool shortName) const
84{
85 return monthName(month(date), shortName);
86}
87
88QString KCalendarSystemGregorian::monthNamePossessive(const QDate& date, bool shortName) const
89{
90 return monthNamePossessive(month(date), shortName);
91}
92
93QString KCalendarSystemGregorian::monthName(int month, bool shortName) const
94{
95// kdDebug(5400) << "Gregorian getMonthName" << endl;
96
97 if ( shortName )
98 switch ( month )
99 {
100 case 1:
101 return locale()->translate("January", "Jan");
102 case 2:
103 return locale()->translate("February", "Feb");
104 case 3:
105 return locale()->translate("March", "Mar");
106 case 4:
107 return locale()->translate("April", "Apr");
108 case 5:
109 return locale()->translate("May short", "May");
110 case 6:
111 return locale()->translate("June", "Jun");
112 case 7:
113 return locale()->translate("July", "Jul");
114 case 8:
115 return locale()->translate("August", "Aug");
116 case 9:
117 return locale()->translate("September", "Sep");
118 case 10:
119 return locale()->translate("October", "Oct");
120 case 11:
121 return locale()->translate("November", "Nov");
122 case 12:
123 return locale()->translate("December", "Dec");
124 }
125 else
126 switch ( month )
127 {
128 case 1:
129 return locale()->translate("January");
130 case 2:
131 return locale()->translate("February");
132 case 3:
133 return locale()->translate("March");
134 case 4:
135 return locale()->translate("April");
136 case 5:
137 return locale()->translate("May long", "May");
138 case 6:
139 return locale()->translate("June");
140 case 7:
141 return locale()->translate("July");
142 case 8:
143 return locale()->translate("August");
144 case 9:
145 return locale()->translate("September");
146 case 10:
147 return locale()->translate("October");
148 case 11:
149 return locale()->translate("November");
150 case 12:
151 return locale()->translate("December");
152 }
153
154 return QString::null;
155}
156
157QString KCalendarSystemGregorian::monthNamePossessive(int month,
158 bool shortName) const
159{
160// kdDebug(5400) << "Gregorian getMonthName" << endl;
161
162 if ( shortName )
163 switch ( month )
164 {
165 case 1:
166 return locale()->translate("of January", "of Jan");
167 case 2:
168 return locale()->translate("of February", "of Feb");
169 case 3:
170 return locale()->translate("of March", "of Mar");
171 case 4:
172 return locale()->translate("of April", "of Apr");
173 case 5:
174 return locale()->translate("of May short", "of May");
175 case 6:
176 return locale()->translate("of June", "of Jun");
177 case 7:
178 return locale()->translate("of July", "of Jul");
179 case 8:
180 return locale()->translate("of August", "of Aug");
181 case 9:
182 return locale()->translate("of September", "of Sep");
183 case 10:
184 return locale()->translate("of October", "of Oct");
185 case 11:
186 return locale()->translate("of November", "of Nov");
187 case 12:
188 return locale()->translate("of December", "of Dec");
189 }
190 else
191 switch ( month )
192 {
193 case 1:
194 return locale()->translate("of January");
195 case 2:
196 return locale()->translate("of February");
197 case 3:
198 return locale()->translate("of March");
199 case 4:
200 return locale()->translate("of April");
201 case 5:
202 return locale()->translate("of May long", "of May");
203 case 6:
204 return locale()->translate("of June");
205 case 7:
206 return locale()->translate("of July");
207 case 8:
208 return locale()->translate("of August");
209 case 9:
210 return locale()->translate("of September");
211 case 10:
212 return locale()->translate("of October");
213 case 11:
214 return locale()->translate("of November");
215 case 12:
216 return locale()->translate("of December");
217 }
218
219 return QString::null;
220}
221
222bool KCalendarSystemGregorian::setYMD(QDate & date, int y, int m, int d) const
223{
224 // We don't want Qt to add 1900 to them
225 if ( y >= 0 && y <= 99 )
226 return false;
227
228 // QDate supports gregorian internally
229 return date.setYMD(y, m, d);
230}
231
232QDate KCalendarSystemGregorian::addYears(const QDate & date, int nyears) const
233{
234#if QT_VERSION >= 300
235 return date.addYears(nyears);
236#else
237 int year = date.year() + nyears;
238 int month = date.month();
239 int day = date.day();
240 QDate newDate( year, month, 1 );
241 if ( day > newDate.daysInMonth() ) day = newDate.daysInMonth();
242 return QDate( year, month, day );
243#endif
244}
245
246QDate KCalendarSystemGregorian::addMonths(const QDate & date, int nmonths) const
247{
248#if QT_VERSION >= 300
249 return date.addMonths(nmonths);
250#else
251 int month = date.month();
252 int nyears;
253 if ( nmonths >= 0 ) {
254 month += nmonths;
255 nyears = ( month - 1 ) / 12;
256 month = ( ( month - 1 ) % 12 ) + 1;
257 } else {
258 nyears = nmonths / 12;
259 // nmonths += nyears * 12;
260 nmonths = nmonths % 12;
261 month += nmonths;
262 if ( month <= 0 ) {
263 month += 12;
264 --nyears;
265 }
266 }
267 int year = date.year() + nyears;
268 int day = date.day();
269 QDate newDate( year, month, 1 );
270 if ( day > newDate.daysInMonth() ) day = newDate.daysInMonth();
271 return QDate( year, month, day );
272#endif
273}
274
275QDate KCalendarSystemGregorian::addDays(const QDate & date, int ndays) const
276{
277 return date.addDays(ndays);
278}
279
280QString KCalendarSystemGregorian::weekDayName(int col, bool shortName) const
281{
282 // ### Should this really be different to each calendar system? Or are we
283 // only going to support weeks with 7 days?
284
285 //kdDebug(5400) << "Gregorian wDayName" << endl;
286 return locale()->weekDayName(col, shortName);
287}
288
289QString KCalendarSystemGregorian::weekDayName(const QDate& date, bool shortName) const
290{
291 return weekDayName(dayOfWeek(date), shortName);
292}
293
294
295int KCalendarSystemGregorian::dayOfWeek(const QDate& date) const
296{
297 return date.dayOfWeek();
298}
299
300int KCalendarSystemGregorian::dayOfYear(const QDate & date) const
301{
302 return date.dayOfYear();
303}
304
305int KCalendarSystemGregorian::daysInMonth(const QDate& date) const
306{
307// kdDebug(5400) << "Gregorian daysInMonth" << endl;
308 return date.daysInMonth();
309}
310
311int KCalendarSystemGregorian::minValidYear() const
312{
313 return 1753; // QDate limit
314}
315
316int KCalendarSystemGregorian::maxValidYear() const
317{
318 return 8000; // QDate limit
319}
320
321int KCalendarSystemGregorian::day(const QDate& date) const
322{
323 return date.day();
324}
325
326int KCalendarSystemGregorian::month(const QDate& date) const
327{
328 return date.month();
329}
330
331int KCalendarSystemGregorian::daysInYear(const QDate& date) const
332{
333 return date.daysInYear();
334}
335
336int KCalendarSystemGregorian::weekDayOfPray() const
337{
338 return 7; // sunday
339}
340
341QString KCalendarSystemGregorian::calendarName() const
342{
343 return QString::fromLatin1("gregorian");
344}
345
346bool KCalendarSystemGregorian::isLunar() const
347{
348 return false;
349}
350
351bool KCalendarSystemGregorian::isLunisolar() const
352{
353 return false;
354}
355
356bool KCalendarSystemGregorian::isSolar() const
357{
358 return true;
359}
diff --git a/microkde/kcalendarsystemgregorian.h b/microkde/kcalendarsystemgregorian.h
new file mode 100644
index 0000000..2eff625
--- a/dev/null
+++ b/microkde/kcalendarsystemgregorian.h
@@ -0,0 +1,90 @@
1/*
2 Copyright (c) 2002 Carlos Moro <cfmoro@correo.uniovi.es>
3 Copyright (c) 2002 Hans Petter Bieker <bieker@kde.org>
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21#ifndef KCALENDARSYSTEMGREGORIAN_H
22#define KCALENDARSYSTEMGREGORIAN_H
23
24#include <qdatetime.h>
25#include <qstring.h>
26
27#include "kcalendarsystem.h"
28
29class KCalendarSystemGregorianPrivate;
30
31/**
32 * This is the Gregorian calendar implementation.
33 *
34 * The Gregorian calender is the most used calendar today. The first year in
35 * the calendar is set to the birth of Christ.
36 *
37 * @see KLocale,KCalendarSystem,KCalendarSystemFactory
38 *
39 * @author Carlos Moro <cfmoro@correo.uniovi.es>
40 * @licence GNU-GPL v.2
41 * @version $Id$
42 * @since 3.2
43 */
44class KCalendarSystemGregorian: public KCalendarSystem
45{
46public:
47 KCalendarSystemGregorian (const KLocale * locale = 0);
48 virtual ~KCalendarSystemGregorian ();
49
50 virtual int year (const QDate & date) const;
51 virtual int month (const QDate & date) const;
52 virtual int day (const QDate & date) const;
53 virtual int dayOfWeek (const QDate & date) const;
54 virtual int dayOfYear (const QDate & date) const;
55
56 virtual bool setYMD(QDate & date, int y, int m, int d) const;
57
58 virtual QDate addYears(const QDate & date, int nyears) const;
59 virtual QDate addMonths(const QDate & date, int nmonths) const;
60 virtual QDate addDays(const QDate & date, int ndays) const;
61
62 virtual int monthsInYear (const QDate & date) const;
63
64 virtual int daysInYear (const QDate & date) const;
65 virtual int daysInMonth (const QDate & date) const;
66 virtual int weeksInYear(int year) const;
67 virtual int weekNumber(const QDate& date, int * yearNum = 0) const;
68
69 virtual QString monthName (int month, bool shortName = false) const;
70 virtual QString monthName (const QDate & date, bool shortName = false ) const;
71 virtual QString monthNamePossessive(int month, bool shortName = false) const;
72 virtual QString monthNamePossessive(const QDate & date, bool shortName = false ) const;
73 virtual QString weekDayName (int weekDay, bool shortName = false) const;
74 virtual QString weekDayName (const QDate & date, bool shortName = false) const;
75
76 virtual int minValidYear () const;
77 virtual int maxValidYear () const;
78 virtual int weekDayOfPray () const;
79
80 virtual QString calendarName() const;
81
82 virtual bool isLunar() const;
83 virtual bool isLunisolar() const;
84 virtual bool isSolar() const;
85
86private:
87 KCalendarSystemGregorianPrivate * d;
88};
89
90#endif
diff --git a/microkde/kcolorbutton.cpp b/microkde/kcolorbutton.cpp
new file mode 100644
index 0000000..433f909
--- a/dev/null
+++ b/microkde/kcolorbutton.cpp
@@ -0,0 +1,36 @@
1#include "kcolorbutton.h"
2#include "kcolordialog.h"
3#include "qapplication.h"
4
5
6#include "qlayout.h"
7
8void KColorButton:: edit()
9{
10
11 KColorDialog* k = new KColorDialog( this );
12 k->setColor( mColor );
13 int res = k->exec();
14 if ( res ) {
15 mColor = k->getColor();
16 setColor ( mColor );
17 emit changed ( mColor );
18 }
19 delete k;
20}
21KColorButton::KColorButton( QWidget *p ):QPushButton( p )
22{
23 int size = 24;
24 if( QApplication::desktop()->width() < 480 )
25 size = 18;
26 setFixedSize( size,size );
27 connect ( this, SIGNAL( clicked() ), this ,SLOT (edit() ));
28
29}
30void KColorButton::setColor ( const QColor & c)
31{
32 mColor = c;
33 QPixmap pix ( height() - 4, width() - 4 );
34 pix.fill( c );
35 setPixmap ( pix );
36}
diff --git a/microkde/kcolorbutton.h b/microkde/kcolorbutton.h
new file mode 100644
index 0000000..88b3774
--- a/dev/null
+++ b/microkde/kcolorbutton.h
@@ -0,0 +1,26 @@
1#ifndef MICROKDE_KCOLORBUTTON_H
2#define MICROKDE_KCOLORBUTTON_H
3
4#include <qpushbutton.h>
5#include <qcolor.h>
6#include <kglobal.h>
7#include <qpixmap.h>
8#include <qlabel.h>
9
10
11class KColorButton : public QPushButton
12{
13Q_OBJECT
14public:
15 KColorButton( QWidget *p );
16 void setColor ( const QColor &);
17 QColor color() const { return mColor ; }
18 signals:
19 void changed(const QColor &);
20private slots:
21 void edit();
22 private:
23 QColor mColor;
24};
25
26#endif
diff --git a/microkde/kcolordialog.cpp b/microkde/kcolordialog.cpp
new file mode 100644
index 0000000..9a76e5e
--- a/dev/null
+++ b/microkde/kcolordialog.cpp
@@ -0,0 +1,92 @@
1#include "kcolordialog.h"
2#include <qdialog.h>
3#include <qlayout.h>
4#include <qlabel.h>
5#include <qslider.h>
6#include <qhbox.h>
7#include <qapplication.h>
8#include <qpushbutton.h>
9
10#include <kglobal.h>
11QColor KColorDialog::getColor( ) const
12{
13 QColor c ( r->value(), g->value(), b->value() );
14 lar->setText ( "R: " + QString::number ( c.red() ) );
15 lag->setText ( "G: " + QString::number ( c.green() ) );
16 lab->setText ( "B: " + QString::number ( c.blue() ) );
17 return c;
18}
19void KColorDialog::setColor( const QColor & d )
20{
21 r->setValue(d.red() );
22 g->setValue(d.green() );
23 b->setValue(d.blue() );
24 old_color->setPalette( QPalette( d.dark(), d ) );
25 lar->setText ( "R: " + QString::number ( d.red() ) );
26 lag->setText ( "G: " + QString::number ( d.green() ) );
27 lab->setText ( "B: " + QString::number ( d.blue() ) );
28
29}
30KColorDialog::KColorDialog( QWidget *p ):QDialog( p, "input-dialog", true )
31{
32 setCaption( i18n("Choose Color") );
33
34 setMaximumSize( QApplication::desktop()->width() - 20, QApplication::desktop()->height() - 40 ); // for zaurus 5500er.
35 QGridLayout* lay = new QGridLayout ( this, 4, 2 );
36 lay->setSpacing( 6 );
37 lay->setMargin( 11 );
38
39 old_color = new QLabel("Old color",this);
40 old_color->setFrameStyle( QFrame::Panel | QFrame::Plain );
41 old_color->setLineWidth( 1 );
42 lay->addWidget(old_color, 0, 0);
43
44 new_color = new QLabel("New color", this);
45 new_color->setFrameStyle( QFrame::Panel | QFrame::Plain );
46 new_color->setLineWidth( 1 );
47 lay->addWidget(new_color, 0, 1);
48 new_color->setAlignment( AlignCenter );
49
50 QHBox* hb = new QHBox ( this );
51 lar = new QLabel( hb );
52 lag = new QLabel( hb );
53 lab = new QLabel( hb );
54 lay->addMultiCellWidget( hb,1,1, 0,1 );
55
56 QLabel* lr = new QLabel ( "Red:", this );
57 lay->addWidget( lr,2,0 );
58 r = new QSlider ( 0, 255, 1, 1, Horizontal, this );
59 lay->addWidget(r ,2,1 );
60
61 QLabel* lg = new QLabel( "Green:",this );
62 lay->addWidget(lg ,3,0 );
63 g = new QSlider ( 0, 255, 1, 1, Horizontal, this );
64 lay->addWidget( g ,3,1 );
65
66 QLabel* lb = new QLabel ( "Blue:",this );
67 lay->addWidget( lb,4,0 );
68 b = new QSlider ( 0, 255, 1, 1, Horizontal, this );
69 lay->addWidget(b ,4,1 );
70
71 QColor d = backgroundColor();
72 r->setValue(d.red() );
73 g->setValue(d.green() );
74 b->setValue(d.blue() );
75 old_color->setPalette( QPalette( d.dark() , d ) );
76 // kannst du wieder reinnehmen, aber es geht auch so.
77 QPushButton * ok = new QPushButton (i18n(" OK "), this );
78 QPushButton * cancel = new QPushButton (i18n(" Cancel "), this );
79
80 lay->addWidget(ok ,5,0 );
81 lay->addWidget(cancel ,5,1 );
82 connect (ok, SIGNAL( clicked() ), this ,SLOT (accept() ));
83 connect (cancel, SIGNAL( clicked() ), this ,SLOT (reject() ));
84 connect (r, SIGNAL( valueChanged ( int ) ), this ,SLOT (updateColor( int ) ));
85 connect (g, SIGNAL( valueChanged ( int ) ), this ,SLOT (updateColor( int ) ));
86 connect (b, SIGNAL( valueChanged ( int ) ), this ,SLOT (updateColor( int ) ));
87}
88void KColorDialog::updateColor( int )
89{
90 QColor c = getColor( ) ;
91 new_color->setPalette( QPalette( c.dark(), c ) );
92}
diff --git a/microkde/kcolordialog.h b/microkde/kcolordialog.h
new file mode 100644
index 0000000..bb2045d
--- a/dev/null
+++ b/microkde/kcolordialog.h
@@ -0,0 +1,25 @@
1#ifndef MINIKDE_KCOLORDIALOG_H
2#define MINIKDE_KCOLORDIALOG_H
3
4#include <qcolor.h>
5
6#include <qdialog.h>
7#include <qslider.h>
8#include <qlabel.h>
9class KColorDialog : public QDialog
10{
11Q_OBJECT
12 public:
13 KColorDialog( QWidget *p );
14 QColor getColor( ) const;
15 void setColor( const QColor &);
16 private:
17 QSlider *r, *g, *b;
18 QLabel * old_color, *new_color;
19 QLabel *lar, *lag, *lab;
20private slots:
21 void updateColor( int );
22};
23
24
25#endif
diff --git a/microkde/kcombobox.h b/microkde/kcombobox.h
new file mode 100644
index 0000000..1a21344
--- a/dev/null
+++ b/microkde/kcombobox.h
@@ -0,0 +1,12 @@
1#ifndef MICROKDE_KCOMBOBOX_H
2#define MICROKDE_KCOMBOBOX_H
3
4#include <qcombobox.h>
5
6class KComboBox : public QComboBox
7{
8 public:
9 KComboBox( QWidget *parent ) : QComboBox( parent ) {}
10};
11
12#endif
diff --git a/microkde/kconfig.cpp b/microkde/kconfig.cpp
new file mode 100644
index 0000000..3f23ed2
--- a/dev/null
+++ b/microkde/kconfig.cpp
@@ -0,0 +1,467 @@
1#include <qfile.h>
2#include <qtextstream.h>
3#include <qwidget.h>
4
5#include "kdebug.h"
6
7#include "kurl.h"
8#include "kstandarddirs.h"
9#include "kconfig.h"
10
11QString KConfig::mGroup = "";
12//QString KConfig::mGroup = "General";
13
14KConfig::KConfig( const QString &fileName )
15 : mFileName( fileName ), mDirty( false )
16{
17 kdDebug() << "KConfig::KConfig(): '" << fileName << "'" << endl;
18
19 load();
20
21}
22
23
24KConfig::~KConfig()
25{
26 sync();
27}
28
29void KConfig::setGroup( const QString &group )
30{
31 kdDebug() << "KConfig::setGroup(): '" << group << "'" << endl;
32
33 mGroup = group;
34
35 if ( mGroup.right( 1 ) != "/" ) mGroup += "/";
36}
37
38//US
39QString KConfig::group() const {
40 return mGroup;
41}
42
43//US added method
44QValueList<int> KConfig::readIntListEntry( const QString & key)
45{
46// qDebug("KConfig::readIntListEntry key=%s:", key.latin1());
47
48 QValueList<int> result;
49
50 QMap<QString,QString>::ConstIterator mit = mStringMap.find( mGroup + key );
51
52 if ( mit == mStringMap.end() ) {
53 return result;
54 }
55
56 QStringList valuesAsStrings = QStringList::split(":", *mit );
57 bool ok = false;
58 bool ok2 = true;
59 int val;
60
61 for ( QStringList::Iterator sit = valuesAsStrings.begin(); sit != valuesAsStrings.end(); ++sit ) {
62 val = (*sit).toInt(&ok);
63 result << val;
64 if (ok == false) {
65 qDebug("KConfig::readIntListEntry str=%s , int=%n:", (*sit).latin1(), &val);
66 ok2 = false;
67 }
68 }
69
70 if (ok2 == false)
71 {
72 kdDebug() << "KConfig::readIntListEntry: error while reading one of the intvalues." << endl;
73 qDebug("KConfig::readIntListEntry: error while reading one of the intvalues.");
74 }
75
76 return result;
77}
78
79int KConfig::readNumEntry( const QString & key, int def )
80{
81 QString res = readEntry(key, QString::number(def ) );
82 bool ok = false;
83 int result = res.toInt(&ok);
84 if ( ok )
85 return result;
86 return def;
87}
88
89QString KConfig::readEntry( const QString &key, const QString &def )
90{
91 QMap<QString,QString>::ConstIterator it = mStringMap.find( mGroup + key );
92
93 if ( it == mStringMap.end() ) {
94 return def;
95 }
96
97 return *it;
98}
99
100QStringList KConfig::readListEntry( const QString &key )
101{
102 QMap<QString,QString>::ConstIterator it = mStringMap.find( mGroup + key );
103
104 if ( it == mStringMap.end() ) {
105 return QStringList();
106 }
107 return QStringList::split(":", *it );
108
109}
110
111bool KConfig::readBoolEntry( const QString &key, bool def )
112{
113 QMap<QString,bool>::ConstIterator it = mBoolMap.find( mGroup + key );
114
115 if ( it == mBoolMap.end() ) {
116 return def;
117 }
118
119 return *it;
120}
121
122QColor KConfig::readColorEntry( const QString & e, QColor *def )
123{
124
125 QStringList l;
126 l = readListEntry( e );
127 if (l.count() != 3 ) {
128 if ( def )
129 return *def;
130 else
131 return QColor();
132 }
133 QColor c ( l[0].toInt(), l[1].toInt(), l[2].toInt() );
134 return c;
135}
136
137QFont KConfig::readFontEntry( const QString & e, QFont *def )
138{
139 QStringList font = readListEntry( e );
140 if ( font.isEmpty() )
141 return *def;
142 QFont f;
143 f.setFamily( font[0]);
144 f.setBold ( font[1] == "bold");
145 f.setPointSize ( font[2].toInt());
146 f.setItalic( font[1] == "italic" );
147 return f;
148}
149
150QDateTime KConfig::readDateTimeEntry( const QString &key, const QDateTime *def )
151{
152 QMap<QString,QDateTime>::ConstIterator it = mDateTimeMap.find( mGroup + key );
153
154 if ( it == mDateTimeMap.end() ) {
155 if ( def ) return *def;
156 else return QDateTime();
157 }
158
159 return *it;
160}
161
162//US added method
163void KConfig::writeEntry( const QString &key, const QValueList<int> &value)
164{
165 QStringList valuesAsStrings;
166
167 QValueList<int>::ConstIterator it;
168
169 for( it = value.begin(); it != value.end(); ++it )
170 {
171 valuesAsStrings << QString::number(*it);
172 }
173
174 mStringMap.insert( mGroup + key, valuesAsStrings.join(":") );
175 mDirty = true;
176}
177
178void KConfig::writeEntry( const QString & key , int num )
179{
180 writeEntry( key, QString::number ( num ) );
181}
182
183void KConfig::writeEntry( const QString &key, const QString &value )
184{
185 mStringMap.insert( mGroup + key, value );
186
187 mDirty = true;
188}
189
190void KConfig::writeEntry( const QString &key, const QStringList &value )
191{
192 mStringMap.insert( mGroup + key, value.join(":") );
193
194 mDirty = true;
195}
196
197void KConfig::writeEntry( const QString &key, bool value)
198{
199 mBoolMap.insert( mGroup + key, value );
200
201 mDirty = true;
202}
203
204void KConfig::writeEntry( const QString & e, const QColor & c )
205{
206 QStringList l;
207 l.append( QString::number ( c.red() ) );
208 l.append( QString::number ( c.green() ) );
209 l.append( QString::number ( c.blue() ) );
210 writeEntry( e, l );
211}
212
213void KConfig::writeEntry( const QString & e , const QFont & f )
214{
215 QStringList font;
216 font.append( f.family());
217 font.append( (!f.bold ()?"nonbold":"bold") );
218 font.append( QString::number ( f.pointSize () ) );
219 font.append( !f.italic ()?"nonitalic":"italic" );
220 writeEntry( e, font );
221}
222
223void KConfig::writeEntry( const QString &key, const QDateTime &dt )
224{
225 mDateTimeMap.insert( mGroup + key, dt );
226}
227
228void KConfig::load()
229{
230 kdDebug() << "KConfig::load(): " << mFileName << endl;
231
232 QFile f( mFileName );
233 if ( !f.open( IO_ReadOnly ) ) {
234 qDebug("KConfig: could not open file %s ",mFileName.latin1() );
235 return;
236 }
237
238 mBoolMap.clear();
239 mStringMap.clear();
240
241 QTextStream t( &f );
242
243 QString line = t.readLine();
244
245 while ( !line.isNull() ) {
246 QStringList tokens = QStringList::split( ",", line );
247 if ( tokens[0] == "bool" ) {
248 bool value = false;
249 if ( tokens[2] == "1" ) value = true;
250 mBoolMap.insert( tokens[1], value );
251 } else if ( tokens[0] == "QString" ) {
252 QString value = tokens[2];
253 mStringMap.insert( tokens[1], value );
254 } else if ( tokens[0] == "QDateTime" ) {
255#if 0
256 int year = tokens[2].toInt();
257 QDateTime dt( QDate( year,
258 tokens[3].toInt(),
259 tokens[4].toInt() ),
260 QTime( tokens[5].toInt(), tokens[6].toInt(),
261 tokens[7].toInt() ) );
262 mDateTimeMap.insert( tokens[1], dt );
263#endif
264 }
265
266 line = t.readLine();
267 }
268}
269
270void KConfig::sync()
271{
272
273 if ( !mDirty ) return;
274 //qDebug("KConfig::sync() %s ",mFileName.latin1() );
275 //kdDebug() << "KConfig::sync(): " << mFileName << endl;
276
277//US I took the following code from a newer version of KDE
278 // Create the containing dir if needed
279 KURL path;
280 path.setPath(mFileName);
281 QString dir=path.directory();
282 KStandardDirs::makeDir(dir);
283
284 QFile f( mFileName );
285 if ( !f.open( IO_WriteOnly ) ) {
286
287 qDebug("KConfig::sync() Can't open file %s ",mFileName.latin1() );
288
289 return;
290 }
291
292 QTextStream t( &f );
293
294 QMap<QString,bool>::ConstIterator itBool;
295 for( itBool = mBoolMap.begin(); itBool != mBoolMap.end(); ++itBool ) {
296 t << "bool," << itBool.key() << "," << ( *itBool ? "1" : "0" ) << endl;
297 }
298
299 QMap<QString,QString>::ConstIterator itString;
300 for( itString = mStringMap.begin(); itString != mStringMap.end(); ++itString ) {
301 t << "QString," << itString.key() << "," << (*itString ) << endl;
302 }
303
304 QMap<QString,QDateTime>::ConstIterator itDateTime;
305 for( itDateTime = mDateTimeMap.begin(); itDateTime != mDateTimeMap.end(); ++itDateTime ) {
306 QDateTime dt = *itDateTime;
307 t << "QDateTime," << itDateTime.key() << ","
308 << dt.date().year() << ","
309 << dt.date().month() << ","
310 << dt.date().day() << ","
311 << dt.time().hour() << ","
312 << dt.time().minute() << ","
313 << dt.time().second() << endl;
314 }
315
316 f.close();
317
318 mDirty = false;
319}
320
321
322//US I took the following deleteGroup method from a newer version from KDE.
323/**
324 * Deletes a configuration entry group
325 *
326 * If the group is not empty and bDeep is false, nothing gets
327 * deleted and false is returned.
328 * If this group is the current group and it is deleted, the
329 * current group is undefined and should be set with setGroup()
330 * before the next operation on the configuration object.
331 *
332 * @param group The name of the group
333 * returns true if we deleted at least one entry.
334 */
335bool KConfig::deleteGroup( const QString& group)
336{
337 bool dirty = false;
338 int pos;
339
340 QMap<QString,bool>::Iterator itBool;
341 for( itBool = mBoolMap.begin(); itBool != mBoolMap.end(); ++itBool )
342 {
343 pos = itBool.key().find( group );
344 if (pos == 0) {
345 mBoolMap.remove(itBool);
346 dirty = true;
347 }
348 }
349
350 QMap<QString,QString>::Iterator itString;
351 for( itString = mStringMap.begin(); itString != mStringMap.end(); ++itString )
352 {
353 pos = itString.key().find( group );
354 if (pos == 0) {
355 mStringMap.remove(itString);
356 dirty = true;
357 }
358 }
359
360 QMap<QString,QDateTime>::Iterator itDateTime;
361 for( itDateTime = mDateTimeMap.begin(); itDateTime != mDateTimeMap.end(); ++itDateTime )
362 {
363 pos = itDateTime.key().find( group );
364 if (pos == 0) {
365 mDateTimeMap.remove(itDateTime);
366 dirty = true;
367 }
368 }
369
370 if (dirty)
371 mDirty = true;
372
373 return dirty;
374
375}
376
377//US I took the following hasGroup method from a newer version from KDE.
378 /**
379 * Returns true if the specified group is known about.
380 *
381 * @param group The group to search for.
382 * @return Whether the group exists.
383 */
384bool KConfig::hasGroup(const QString &group) const
385{
386 QMap<QString,bool>::ConstIterator itBool;
387 for( itBool = mBoolMap.begin(); itBool != mBoolMap.end(); ++itBool )
388 {
389 if (itBool.key().find( group ) == 0) {
390 return true;
391 }
392 }
393
394 QMap<QString,QString>::ConstIterator itString;
395 for( itString = mStringMap.begin(); itString != mStringMap.end(); ++itString )
396 {
397 if (itString.key().find( group ) == 0) {
398 return true;
399 }
400 }
401
402 QMap<QString,QDateTime>::ConstIterator itDateTime;
403 for( itDateTime = mDateTimeMap.begin(); itDateTime != mDateTimeMap.end(); ++itDateTime )
404 {
405 if (itDateTime.key().find( group ) == 0) {
406 return true;
407 }
408 }
409
410 return false;
411}
412
413void KConfig::deleteEntry( const QString &key)
414{
415 bool dirty = false;
416
417 QMap<QString,bool>::Iterator itBool = mBoolMap.find( mGroup + key );
418 if ( itBool != mBoolMap.end() ) {
419 mBoolMap.remove(itBool);
420 dirty = true;
421 }
422
423
424 QMap<QString,QString>::Iterator itString = mStringMap.find( mGroup + key );
425 if ( itString != mStringMap.end() ) {
426 mStringMap.remove(itString);
427 dirty = true;
428 }
429
430
431 QMap<QString,QDateTime>::Iterator itDateTime = mDateTimeMap.find( mGroup + key );
432 if ( itDateTime != mDateTimeMap.end() ) {
433 mDateTimeMap.remove(itDateTime);
434 dirty = true;
435 }
436
437 if (dirty)
438 mDirty = true;
439
440}
441
442//US
443QString KConfig::getFileName()
444{
445 return mFileName;
446}
447
448bool KConfig::hasKey( const QString &key)
449{
450 QMap<QString,bool>::Iterator itBool = mBoolMap.find( mGroup + key );
451 if ( itBool != mBoolMap.end() ) {
452 return true;
453 }
454
455 QMap<QString,QString>::Iterator itString = mStringMap.find( mGroup + key );
456 if ( itString != mStringMap.end() ) {
457 return true;
458 }
459
460 QMap<QString,QDateTime>::Iterator itDateTime = mDateTimeMap.find( mGroup + key );
461 if ( itDateTime != mDateTimeMap.end() ) {
462 return true;
463 }
464
465 return false;
466}
467
diff --git a/microkde/kconfig.h b/microkde/kconfig.h
new file mode 100644
index 0000000..bfedf53
--- a/dev/null
+++ b/microkde/kconfig.h
@@ -0,0 +1,100 @@
1#ifndef MINIKDE_KCONFIG_H
2#define MINIKDE_KCONFIG_H
3
4#include <qstring.h>
5#include <qstringlist.h>
6#include <qvaluelist.h>
7#include <qcolor.h>
8#include <qfont.h>
9#include <qmap.h>
10#include <qdatetime.h>
11
12class KConfig
13{
14 public:
15 KConfig( const QString & );
16 ~KConfig();
17
18 void setGroup( const QString & );
19
20//US
21 /**
22 * Returns the name of the group in which we are
23 * searching for keys and from which we are retrieving entries.
24 *
25 * @return The current group.
26 */
27 QString group() const;
28
29//US I took the following deleteGroup method from a newer version from KDE.
30/**
31 * Deletes a configuration entry group
32 *
33 * If the group is not empty and bDeep is false, nothing gets
34 * deleted and false is returned.
35 * If this group is the current group and it is deleted, the
36 * current group is undefined and should be set with setGroup()
37 * before the next operation on the configuration object.
38 *
39 * @param group The name of the group
40 * returns true if we deleted at least one entry.
41 */
42 bool deleteGroup( const QString& group);
43
44//US I took the following hasGroup method from a newer version from KDE.
45 /**
46 * Returns true if the specified group is known about.
47 *
48 * @param group The group to search for.
49 * @return Whether the group exists.
50 */
51 bool hasGroup(const QString &group) const;
52
53
54 QString getFileName();
55
56//US added method readIntListEntry
57 QValueList<int> readIntListEntry( const QString &);
58
59 int readNumEntry( const QString &, int def=0 );
60 QString readEntry( const QString &, const QString &def=QString::null );
61 QStringList readListEntry( const QString & );
62 bool readBoolEntry( const QString &, bool def=false );
63 QColor readColorEntry( const QString &, QColor * );
64 QFont readFontEntry( const QString &, QFont * );
65 QDateTime readDateTimeEntry( const QString &, const QDateTime *pDefault = 0 );
66
67 bool hasKey( const QString &);
68
69 void writeEntry( const QString &, const QValueList<int>& );
70 void writeEntry( const QString &, int );
71 void writeEntry( const QString &key , unsigned int value) { writeEntry( key, int( value ) ); }
72 void writeEntry( const char *key , unsigned int value) { writeEntry( QString( key ), value ); }
73 void writeEntry( const char *key, int value ) { writeEntry( QString( key ), value ); }
74 void writeEntry( const QString &, const QString & );
75 void writeEntry( const char *key, const QString &value ) { writeEntry( QString( key ), value ); }
76 void writeEntry( const QString &, const QStringList & );
77 void writeEntry( const QString &, bool );
78 void writeEntry( const char *key, bool value ) { writeEntry( QString( key ), value ); }
79 void writeEntry( const QString &, const QColor & );
80 void writeEntry( const QString &, const QFont & );
81 void writeEntry( const QString &, const QDateTime & );
82
83 void deleteEntry( const QString &);
84
85 void load();
86 void sync();
87
88 private:
89 static QString mGroup;
90
91 QString mFileName;
92
93 QMap<QString,bool> mBoolMap;
94 QMap<QString,QString> mStringMap;
95 QMap<QString,QDateTime> mDateTimeMap;
96
97 bool mDirty;
98};
99
100#endif
diff --git a/microkde/kconfigtest.cpp b/microkde/kconfigtest.cpp
new file mode 100644
index 0000000..373d674
--- a/dev/null
+++ b/microkde/kconfigtest.cpp
@@ -0,0 +1,14 @@
1#include "kconfig.h"
2#include "kdebug.h"
3
4#include <qdatetime.h>
5
6int main()
7{
8 QDateTime dt = QDateTime::currentDateTime();
9 kdDebug() << "Before: " << dt.toString() << endl;
10 KConfig cfg( "huhu" );
11 cfg.writeEntry( "123", dt );
12 QDateTime newDt = cfg.readDateTimeEntry( "123" );
13 kdDebug() << "After: " << newDt.toString() << endl;
14}
diff --git a/microkde/kdatepickernew.cpp b/microkde/kdatepickernew.cpp
new file mode 100644
index 0000000..f60a422
--- a/dev/null
+++ b/microkde/kdatepickernew.cpp
@@ -0,0 +1,485 @@
1/* -*- C++ -*-
2 This file is part of the KDE libraries
3 Copyright (C) 1997 Tim D. Gilman (tdgilman@best.org)
4 (C) 1998-2001 Mirko Boehm (mirko@kde.org)
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21#include <qlayout.h>
22#include <qframe.h>
23#include <qpainter.h>
24#include <qdialog.h>
25#include <qstyle.h>
26#include <qtoolbutton.h>
27#include <qcombobox.h>
28#include <qtooltip.h>
29#include <qfont.h>
30#include <qvalidator.h>
31#include <qpopupmenu.h>
32
33#include "kdatepicker.h"
34#include <kglobal.h>
35#include <kapplication.h>
36#include <klocale.h>
37#include <kiconloader.h>
38#include <ktoolbar.h>
39#include <klineedit.h>
40#include <kdebug.h>
41#include <knotifyclient.h>
42#include <kcalendarsystem.h>
43
44#include "kdatetbl.h"
45#include "kdatepicker.moc"
46
47class KDatePicker::KDatePickerPrivate
48{
49public:
50 KDatePickerPrivate() : closeButton(0L), selectWeek(0L), todayButton(0), navigationLayout(0) {}
51
52 void fillWeeksCombo(const QDate &date);
53
54 KToolBar *tb;
55 QToolButton *closeButton;
56 QComboBox *selectWeek;
57 QToolButton *todayButton;
58 QBoxLayout *navigationLayout;
59};
60
61void KDatePicker::fillWeeksCombo(const QDate &date)
62{
63 // every year can have a different number of weeks
64 const KCalendarSystem * calendar = KGlobal::locale()->calendar();
65 int i, weeks = calendar->weeksInYear(calendar->year(date));
66
67 if ( d->selectWeek->count() == weeks ) return; // we already have the correct number
68
69 d->selectWeek->clear();
70
71 for (i = 1; i <= weeks; i++)
72 d->selectWeek->insertItem(i18n("Week %1").arg(i));
73}
74
75KDatePicker::KDatePicker(QWidget *parent, QDate dt, const char *name)
76 : QFrame(parent,name)
77{
78 init( dt );
79}
80
81KDatePicker::KDatePicker(QWidget *parent, QDate dt, const char *name, WFlags f)
82 : QFrame(parent,name, f)
83{
84 init( dt );
85}
86
87KDatePicker::KDatePicker( QWidget *parent, const char *name )
88 : QFrame(parent,name)
89{
90 init( QDate::currentDate() );
91}
92
93void KDatePicker::init( const QDate &dt )
94{
95 d = new KDatePickerPrivate();
96
97 d->tb = new KToolBar(this);
98
99 yearBackward = new QToolButton(d->tb);
100 monthBackward = new QToolButton(d->tb);
101 selectMonth = new QToolButton(d->tb);
102 selectYear = new QToolButton(d->tb);
103 monthForward = new QToolButton(d->tb);
104 yearForward = new QToolButton(d->tb);
105 line = new KLineEdit(this);
106 val = new KDateValidator(this);
107 table = new KDateTable(this);
108 fontsize = 12;//KGlobalSettings::generalFont().pointSize();
109
110
111 fontsize++; // Make a little bigger
112
113 d->selectWeek = new QComboBox(false, this); // read only week selection
114 d->todayButton = new QToolButton(this);
115 d->todayButton->setIconSet(SmallIconSet("today"));
116
117 QToolTip::add(yearForward, i18n("Next year"));
118 QToolTip::add(yearBackward, i18n("Previous year"));
119 QToolTip::add(monthForward, i18n("Next month"));
120 QToolTip::add(monthBackward, i18n("Previous month"));
121 QToolTip::add(d->selectWeek, i18n("Select a week"));
122 QToolTip::add(selectMonth, i18n("Select a month"));
123 QToolTip::add(selectYear, i18n("Select a year"));
124 QToolTip::add(d->todayButton, i18n("Select the current day"));
125
126 // -----
127 setFontSize(fontsize);
128 line->setValidator(val);
129 line->installEventFilter( this );
130// yearForward->setIconSet(BarIconSet(QString::fromLatin1("2rightarrow")));
131// yearBackward->setIconSet(BarIconSet(QString::fromLatin1("2leftarrow")));
132// monthForward->setIconSet(BarIconSet(QString::fromLatin1("1rightarrow")));
133// monthBackward->setIconSet(BarIconSet(QString::fromLatin1("1leftarrow")));
134 setDate(dt); // set button texts
135 connect(table, SIGNAL(dateChanged(QDate)), SLOT(dateChangedSlot(QDate)));
136 connect(table, SIGNAL(tableClicked()), SLOT(tableClickedSlot()));
137 connect(monthForward, SIGNAL(clicked()), SLOT(monthForwardClicked()));
138 connect(monthBackward, SIGNAL(clicked()), SLOT(monthBackwardClicked()));
139 connect(yearForward, SIGNAL(clicked()), SLOT(yearForwardClicked()));
140 connect(yearBackward, SIGNAL(clicked()), SLOT(yearBackwardClicked()));
141 connect(d->selectWeek, SIGNAL(activated(int)), SLOT(weekSelected(int)));
142 connect(d->todayButton, SIGNAL(clicked()), SLOT(todayButtonClicked()));
143 connect(selectMonth, SIGNAL(clicked()), SLOT(selectMonthClicked()));
144 connect(selectYear, SIGNAL(clicked()), SLOT(selectYearClicked()));
145 connect(line, SIGNAL(returnPressed()), SLOT(lineEnterPressed()));
146 table->setFocus();
147
148 QBoxLayout * topLayout = new QVBoxLayout(this);
149
150 d->navigationLayout = new QHBoxLayout(topLayout);
151 d->navigationLayout->addWidget(d->tb);
152
153 topLayout->addWidget(table);
154
155 QBoxLayout * bottomLayout = new QHBoxLayout(topLayout);
156 bottomLayout->addWidget(d->todayButton);
157 bottomLayout->addWidget(line);
158 bottomLayout->addWidget(d->selectWeek);
159}
160
161KDatePicker::~KDatePicker()
162{
163 delete d;
164}
165
166bool
167KDatePicker::eventFilter(QObject *o, QEvent *e )
168{
169 if ( e->type() == QEvent::KeyPress ) {
170 QKeyEvent *k = (QKeyEvent *)e;
171
172 if ( (k->key() == Qt::Key_Prior) ||
173 (k->key() == Qt::Key_Next) ||
174 (k->key() == Qt::Key_Up) ||
175 (k->key() == Qt::Key_Down) )
176 {
177 QApplication::sendEvent( table, e );
178 table->setFocus();
179 return true; // eat event
180 }
181 }
182 return QFrame::eventFilter( o, e );
183}
184
185void
186KDatePicker::resizeEvent(QResizeEvent* e)
187{
188 QWidget::resizeEvent(e);
189}
190
191void
192KDatePicker::dateChangedSlot(QDate date)
193{
194 kdDebug(298) << "KDatePicker::dateChangedSlot: date changed (" << date.year() << "/" << date.month() << "/" << date.day() << ")." << endl;
195
196 const KCalendarSystem * calendar = KGlobal::locale()->calendar();
197
198 line->setText(KGlobal::locale()->formatDate(date, true));
199 selectMonth->setText(calendar->monthName(date, false));
200 fillWeeksCombo(date);
201 d->selectWeek->setCurrentItem(calendar->weekNumber(date) - 1);
202 selectYear->setText(calendar->yearString(date, false));
203
204 emit(dateChanged(date));
205}
206
207void
208KDatePicker::tableClickedSlot()
209{
210 kdDebug(298) << "KDatePicker::tableClickedSlot: table clicked." << endl;
211 emit(dateSelected(table->getDate()));
212 emit(tableClicked());
213}
214
215const QDate&
216KDatePicker::getDate() const
217{
218 return table->getDate();
219}
220
221const QDate &
222KDatePicker::date() const
223{
224 return table->getDate();
225}
226
227bool
228KDatePicker::setDate(const QDate& date)
229{
230 if(date.isValid())
231 {
232 const KCalendarSystem * calendar = KGlobal::locale()->calendar();
233
234 table->setDate(date);
235 fillWeeksCombo(date);
236 d->selectWeek->setCurrentItem(calendar->weekNumber(date) - 1);
237 selectMonth->setText(calendar->monthName(date, false));
238 selectYear->setText(calendar->yearString(date, true));
239 line->setText(KGlobal::locale()->formatDate(date, true));
240 return true;
241 }
242 else
243 {
244 kdDebug(298) << "KDatePicker::setDate: refusing to set invalid date." << endl;
245 return false;
246 }
247}
248
249void
250KDatePicker::monthForwardClicked()
251{
252 QDate temp;
253 temp = KGlobal::locale()->calendar()->addMonths( table->getDate(), 1 );
254
255 setDate( temp );
256}
257
258void
259KDatePicker::monthBackwardClicked()
260{
261 QDate temp;
262 temp = KGlobal::locale()->calendar()->addMonths( table->getDate(), -1 );
263
264 setDate( temp );
265}
266
267void
268KDatePicker::yearForwardClicked()
269{
270 QDate temp;
271 temp = KGlobal::locale()->calendar()->addYears( table->getDate(), 1 );
272
273 setDate( temp );
274}
275
276void
277KDatePicker::yearBackwardClicked()
278{
279 QDate temp;
280 temp = KGlobal::locale()->calendar()->addYears( table->getDate(), -1 );
281
282 setDate( temp );
283}
284
285void KDatePicker::selectWeekClicked() {} // ### in 3.2 obsolete; kept for binary compatibility
286
287void
288KDatePicker::weekSelected(int week)
289{
290 week++; // week number starts with 1
291
292 const KCalendarSystem * calendar = KGlobal::locale()->calendar();
293
294 QDate date = table->getDate();
295 int year = calendar->year(date);
296
297 calendar->setYMD(date, year, 1, 1);
298 date = calendar->addDays(date, -7);
299 while (calendar->weekNumber(date) != 1)
300 date = calendar->addDays(date, 1);
301
302 // date is now first day in week 1 some day in week 1
303 date = calendar->addDays(date, (week - calendar->weekNumber(date)) * 7);
304
305 setDate(date);
306}
307
308void
309KDatePicker::selectMonthClicked()
310{
311 // every year can have different month names (in some calendar systems)
312 const KCalendarSystem * calendar = KGlobal::locale()->calendar();
313 QDate date = table->getDate();
314 int i, month, months = calendar->monthsInYear(date);
315
316 QPopupMenu popup(selectMonth);
317
318 for (i = 1; i <= months; i++)
319 popup.insertItem(calendar->monthName(i, calendar->year(date)), i);
320
321 popup.setActiveItem(calendar->month(date) - 1);
322
323 if ( (month = popup.exec(selectMonth->mapToGlobal(QPoint(0, 0)), calendar->month(date) - 1)) == -1 ) return; // canceled
324
325 int day = calendar->day(date);
326 // ----- construct a valid date in this month:
327 //date.setYMD(date.year(), month, 1);
328 //date.setYMD(date.year(), month, QMIN(day, date.daysInMonth()));
329 calendar->setYMD(date, calendar->year(date), month,
330 QMIN(day, calendar->daysInMonth(date)));
331 // ----- set this month
332 setDate(date);
333}
334
335void
336KDatePicker::selectYearClicked()
337{
338 const KCalendarSystem * calendar = KGlobal::locale()->calendar();
339
340 int year;
341 KPopupFrame* popup = new KPopupFrame(this);
342 KDateInternalYearSelector* picker = new KDateInternalYearSelector(popup);
343 // -----
344 picker->resize(picker->sizeHint());
345 popup->setMainWidget(picker);
346 connect(picker, SIGNAL(closeMe(int)), popup, SLOT(close(int)));
347 picker->setFocus();
348 if(popup->exec(selectYear->mapToGlobal(QPoint(0, selectMonth->height()))))
349 {
350 QDate date;
351 int day;
352 // -----
353 year=picker->getYear();
354 date=table->getDate();
355 day=calendar->day(date);
356 // ----- construct a valid date in this month:
357 //date.setYMD(year, date.month(), 1);
358 //date.setYMD(year, date.month(), QMIN(day, date.daysInMonth()));
359 calendar->setYMD(date, year, calendar->month(date),
360 QMIN(day, calendar->daysInMonth(date)));
361 // ----- set this month
362 setDate(date);
363 } else {
364 KNotifyClient::beep();
365 }
366 delete popup;
367}
368
369void
370KDatePicker::setEnabled(bool enable)
371{
372 QWidget *widgets[]= {
373 yearForward, yearBackward, monthForward, monthBackward,
374 selectMonth, selectYear,
375 line, table, d->selectWeek, d->todayButton };
376 const int Size=sizeof(widgets)/sizeof(widgets[0]);
377 int count;
378 // -----
379 for(count=0; count<Size; ++count)
380 {
381 widgets[count]->setEnabled(enable);
382 }
383}
384
385void
386KDatePicker::lineEnterPressed()
387{
388 QDate temp;
389 // -----
390 if(val->date(line->text(), temp)==QValidator::Acceptable)
391 {
392 kdDebug(298) << "KDatePicker::lineEnterPressed: valid date entered." << endl;
393 emit(dateEntered(temp));
394 setDate(temp);
395 } else {
396 KNotifyClient::beep();
397 kdDebug(298) << "KDatePicker::lineEnterPressed: invalid date entered." << endl;
398 }
399}
400
401void
402KDatePicker::todayButtonClicked()
403{
404 setDate(QDate::currentDate());
405}
406
407QSize
408KDatePicker::sizeHint() const
409{
410 return QWidget::sizeHint();
411}
412
413void
414KDatePicker::setFontSize(int s)
415{
416 QWidget *buttons[]= {
417 // yearBackward,
418 // monthBackward,
419 selectMonth,
420 selectYear,
421 // monthForward,
422 // yearForward
423 };
424 const int NoOfButtons=sizeof(buttons)/sizeof(buttons[0]);
425 int count;
426 QFont font;
427 QRect r;
428 // -----
429 fontsize=s;
430 for(count=0; count<NoOfButtons; ++count)
431 {
432 font=buttons[count]->font();
433 font.setPointSize(s);
434 buttons[count]->setFont(font);
435 }
436 QFontMetrics metrics(selectMonth->fontMetrics());
437
438 for (int i = 1; ; ++i)
439 {
440 QString str = KGlobal::locale()->calendar()->monthName(i,
441 KGlobal::locale()->calendar()->year(table->getDate()), false);
442 if (str.isNull()) break;
443 r=metrics.boundingRect(str);
444 maxMonthRect.setWidth(QMAX(r.width(), maxMonthRect.width()));
445 maxMonthRect.setHeight(QMAX(r.height(), maxMonthRect.height()));
446 }
447
448 QSize metricBound = style().sizeFromContents(QStyle::CT_ToolButton,
449 selectMonth,
450 maxMonthRect);
451 selectMonth->setMinimumSize(metricBound);
452
453 table->setFontSize(s);
454}
455
456void
457KDatePicker::setCloseButton( bool enable )
458{
459 if ( enable == (d->closeButton != 0L) )
460 return;
461
462 if ( enable ) {
463 d->closeButton = new QToolButton( d->tb );
464 d->navigationLayout->addWidget(d->closeButton);
465 QToolTip::add(d->closeButton, i18n("Close"));
466 d->closeButton->setPixmap( SmallIcon("remove") );
467 connect( d->closeButton, SIGNAL( clicked() ),
468 topLevelWidget(), SLOT( close() ) );
469 }
470 else {
471 delete d->closeButton;
472 d->closeButton = 0L;
473 }
474
475 updateGeometry();
476}
477
478bool KDatePicker::hasCloseButton() const
479{
480 return (d->closeButton != 0L);
481}
482
483void KDatePicker::virtual_hook( int /*id*/, void* /*data*/ )
484{ /*BASE::virtual_hook( id, data );*/ }
485
diff --git a/microkde/kdatepickernew.h b/microkde/kdatepickernew.h
new file mode 100644
index 0000000..9ea909d
--- a/dev/null
+++ b/microkde/kdatepickernew.h
@@ -0,0 +1,253 @@
1/* -*- C++ -*-
2 This file is part of the KDE libraries
3 Copyright (C) 1997 Tim D. Gilman (tdgilman@best.org)
4 (C) 1998-2001 Mirko Boehm (mirko@kde.org)
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20#ifndef KDATEPICKER_H
21#define KDATEPICKER_H
22#include <qdatetime.h>
23#include <qframe.h>
24#include <kdemacros.h>
25
26class QLineEdit;
27class QToolButton;
28class KDateValidator;
29class KDateTable;
30
31/**
32 * Provides a widget for calendar date input.
33 *
34 * Different from the
35 * previous versions, it now emits two types of signals, either
36 * dateSelected() or dateEntered() (see documentation for both
37 * signals).
38 *
39 * A line edit has been added in the newer versions to allow the user
40 * to select a date directly by entering numbers like 19990101
41 * or 990101.
42 *
43 * \image html kdatepicker.png "KDE Date Widget"
44 *
45 * @version $Id$
46 * @author Tim Gilman, Mirko Boehm
47 *
48 * @short A date selection widget.
49 **/
50class KDatePicker: public QFrame
51{
52 Q_OBJECT
53 Q_PROPERTY( QDate date READ date WRITE setDate)
54 Q_PROPERTY( bool closeButton READ hasCloseButton WRITE setCloseButton )
55 Q_PROPERTY( int fontSize READ fontSize WRITE setFontSize )
56
57public:
58 /** The usual constructor. The given date will be displayed
59 * initially.
60 **/
61 KDatePicker(QWidget *parent=0,
62 QDate=QDate::currentDate(),
63 const char *name=0);
64
65 /** The usual constructor. The given date will be displayed
66 * initially.
67 * @since 3.1
68 **/
69 KDatePicker(QWidget *parent,
70 QDate,
71 const char *name,
72 WFlags f); // ### KDE 4.0: Merge
73
74 /**
75 * Standard qt widget constructor. The initial date will be the
76 * current date.
77 * @since 3.1
78 */
79 KDatePicker( QWidget *parent, const char *name );
80
81 /**
82 * The destructor.
83 **/
84 virtual ~KDatePicker();
85
86 /** The size hint for date pickers. The size hint recommends the
87 * minimum size of the widget so that all elements may be placed
88 * without clipping. This sometimes looks ugly, so when using the
89 * size hint, try adding 28 to each of the reported numbers of
90 * pixels.
91 **/
92 QSize sizeHint() const;
93
94 /**
95 * Sets the date.
96 *
97 * @returns @p false and does not change anything
98 * if the date given is invalid.
99 **/
100 bool setDate(const QDate&);
101
102 /**
103 * Returns the selected date.
104 * @deprecated
105 **/
106 const QDate& getDate() const KDE_DEPRECATED;
107
108 /**
109 * @returns the selected date.
110 */
111 const QDate &date() const;
112
113 /**
114 * Enables or disables the widget.
115 **/
116 void setEnabled(bool);
117
118 /**
119 * @returns the KDateTable widget child of this KDatePicker
120 * widget.
121 * @since 3.2
122 */
123 KDateTable *dateTable() const { return table; };
124
125 /**
126 * Sets the font size of the widgets elements.
127 **/
128 void setFontSize(int);
129 /**
130 * Returns the font size of the widget elements.
131 */
132 int fontSize() const
133 { return fontsize; }
134
135 /**
136 * By calling this method with @p enable = true, KDatePicker will show
137 * a little close-button in the upper button-row. Clicking the
138 * close-button will cause the KDatePicker's topLevelWidget()'s close()
139 * method being called. This is mostly useful for toplevel datepickers
140 * without a window manager decoration.
141 * @see hasCloseButton
142 * @since 3.1
143 */
144 void setCloseButton( bool enable );
145
146 /**
147 * @returns true if a KDatePicker shows a close-button.
148 * @see setCloseButton
149 * @since 3.1
150 */
151 bool hasCloseButton() const;
152
153protected:
154 /// to catch move keyEvents when QLineEdit has keyFocus
155 virtual bool eventFilter(QObject *o, QEvent *e );
156 /// the resize event
157 virtual void resizeEvent(QResizeEvent*);
158 /// the year forward button
159 QToolButton *yearForward;
160 /// the year backward button
161 QToolButton *yearBackward;
162 /// the month forward button
163 QToolButton *monthForward;
164 /// the month backward button
165 QToolButton *monthBackward;
166 /// the button for selecting the month directly
167 QToolButton *selectMonth;
168 /// the button for selecting the year directly
169 QToolButton *selectYear;
170 /// the line edit to enter the date directly
171 QLineEdit *line;
172 /// the validator for the line edit:
173 KDateValidator *val;
174 /// the date table
175 KDateTable *table;
176 /// the size calculated during resize events
177 // QSize sizehint;
178 /// the widest month string in pixels:
179 QSize maxMonthRect;
180protected slots:
181 void dateChangedSlot(QDate);
182 void tableClickedSlot();
183 void monthForwardClicked();
184 void monthBackwardClicked();
185 void yearForwardClicked();
186 void yearBackwardClicked();
187 /**
188 * @since 3.1
189 * @deprecated in 3.2
190 */
191 void selectWeekClicked() KDE_DEPRECATED;
192 /**
193 * @since 3.1
194 */
195 void selectMonthClicked();
196 /**
197 * @since 3.1
198 */
199 void selectYearClicked();
200 /**
201 * @since 3.1
202 */
203 void lineEnterPressed();
204 /**
205 * @since 3.2
206 */
207 void todayButtonClicked();
208 /**
209 * @since 3.2
210 */
211 void weekSelected(int);
212
213signals:
214 // ### KDE 4.0 Make all QDate parameters const references
215
216 /** This signal is emitted each time the selected date is changed.
217 * Usually, this does not mean that the date has been entered,
218 * since the date also changes, for example, when another month is
219 * selected.
220 * @see dateSelected
221 */
222 void dateChanged(QDate);
223 /** This signal is emitted each time a day has been selected by
224 * clicking on the table (hitting a day in the current month). It
225 * has the same meaning as dateSelected() in older versions of
226 * KDatePicker.
227 */
228 void dateSelected(QDate);
229 /** This signal is emitted when enter is pressed and a VALID date
230 * has been entered before into the line edit. Connect to both
231 * dateEntered() and dateSelected() to receive all events where the
232 * user really enters a date.
233 */
234 void dateEntered(QDate);
235 /** This signal is emitted when the day has been selected by
236 * clicking on it in the table.
237 */
238 void tableClicked();
239
240private:
241 /// the font size for the widget
242 int fontsize;
243
244protected:
245 virtual void virtual_hook( int id, void* data );
246private:
247 void init( const QDate &dt );
248 void fillWeeksCombo(const QDate &date);
249 class KDatePickerPrivate;
250 KDatePickerPrivate *d;
251};
252
253#endif // KDATEPICKER_H
diff --git a/microkde/kdatetbl.cpp b/microkde/kdatetbl.cpp
new file mode 100644
index 0000000..0a2d1f5
--- a/dev/null
+++ b/microkde/kdatetbl.cpp
@@ -0,0 +1,735 @@
1/* -*- C++ -*-
2 This file is part of the KDE libraries
3 Copyright (C) 1997 Tim D. Gilman (tdgilman@best.org)
4 (C) 1998-2001 Mirko Boehm (mirko@kde.org)
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21/////////////////// KDateTable widget class //////////////////////
22//
23// Copyright (C) 1997 Tim D. Gilman
24// (C) 1998-2001 Mirko Boehm
25// Written using Qt (http://www.troll.no) for the
26// KDE project (http://www.kde.org)
27//
28// This is a support class for the KDatePicker class. It just
29// draws the calender table without titles, but could theoretically
30// be used as a standalone.
31//
32// When a date is selected by the user, it emits a signal:
33// dateSelected(QDate)
34
35#include <kglobal.h>
36#include <kglobalsettings.h>
37#include <kapplication.h>
38#include <klocale.h>
39#include <kdebug.h>
40#include <knotifyclient.h>
41#include "kdatetbl.h"
42#include <qdatetime.h>
43#include <qstring.h>
44#include <qpen.h>
45#include <qpainter.h>
46#include <qdialog.h>
47#include <assert.h>
48#include <qapplication.h>
49
50KDateValidator::KDateValidator(QWidget* parent, const char* name)
51 : QValidator(parent, name)
52{
53}
54
55QValidator::State
56KDateValidator::validate(QString& text, int&) const
57{
58 QDate temp;
59 // ----- everything is tested in date():
60 return date(text, temp);
61}
62
63QValidator::State
64KDateValidator::date(const QString& text, QDate& d) const
65{
66 QDate tmp = KGlobal::locale()->readDate(text);
67 if (!tmp.isNull())
68 {
69 d = tmp;
70 return Acceptable;
71 } else
72 return Valid;
73}
74
75void
76KDateValidator::fixup( QString& ) const
77{
78
79}
80
81KDateTable::KDateTable(QWidget *parent, QDate date_, const char* name, WFlags f)
82 : QGridView(parent, name, f)
83{
84 setFontSize(10);
85 if(!date_.isValid())
86 {
87 date_=QDate::currentDate();
88 }
89 setFocusPolicy( QWidget::StrongFocus );
90 setNumRows(7); // 6 weeks max + headline
91 setNumCols(7); // 7 days a week
92 setHScrollBarMode(AlwaysOff);
93 setVScrollBarMode(AlwaysOff);
94 viewport()->setBackgroundColor(QColor(220,245,255));
95#if 0
96 viewport()->setEraseColor(lightGray);
97#endif
98 setDate(date_); // this initializes firstday, numdays, numDaysPrevMonth
99}
100
101void
102KDateTable::paintCell(QPainter *painter, int row, int col)
103{
104 QRect rect;
105 QString text;
106 QPen pen;
107 int w=cellWidth();
108 int h=cellHeight();
109 int pos;
110 QBrush brushBlue(blue);
111 QBrush brushLightblue(QColor(220,245,255));
112 QFont font=KGlobalSettings::generalFont();
113 // -----
114 font.setPointSize(fontsize);
115 if(row==0)
116 { // we are drawing the headline
117 font.setBold(true);
118 painter->setFont(font);
119 bool normalday = true;
120 QString daystr;
121 if (KGlobal::locale()->weekStartsMonday())
122 {
123 daystr = KGlobal::locale()->weekDayName(col+1, true);
124 if (col == 5 || col == 6)
125 normalday = false;
126 } else {
127 daystr = KGlobal::locale()->weekDayName(col==0? 7 : col, true);
128 if (col == 0 || col == 6)
129 normalday = false;
130 }
131 if (!normalday)
132 {
133 painter->setPen(QColor(220,245,255));
134 painter->setBrush(brushLightblue);
135 painter->drawRect(0, 0, w, h);
136 painter->setPen(blue);
137 } else {
138 painter->setPen(blue);
139 painter->setBrush(brushBlue);
140 painter->drawRect(0, 0, w, h);
141 painter->setPen(white);
142 }
143 painter->drawText(0, 0, w, h-1, AlignCenter,
144 daystr, -1, &rect);
145 painter->setPen(black);
146 painter->moveTo(0, h-1);
147 painter->lineTo(w-1, h-1);
148 // ----- draw the weekday:
149 } else {
150 painter->setFont(font);
151 pos=7*(row-1)+col;
152 if (KGlobal::locale()->weekStartsMonday())
153 pos++;
154 if(pos<firstday || (firstday+numdays<=pos))
155 { // we are either
156 // ° painting a day of the previous month or
157 // ° painting a day of the following month
158 if(pos<firstday)
159 { // previous month
160 text.setNum(numDaysPrevMonth+pos-firstday+1);
161 } else { // following month
162 text.setNum(pos-firstday-numdays+1);
163 }
164 painter->setPen(gray);
165 } else { // paint a day of the current month
166 text.setNum(pos-firstday+1);
167 painter->setPen(black);
168 }
169
170 pen=painter->pen();
171 if(firstday+date.day()-1==pos)
172 {
173 if(hasFocus())
174 { // draw the currently selected date
175 painter->setPen(red);
176 painter->setBrush(darkRed);
177 pen=white;
178 } else {
179 painter->setPen(darkGray);
180 painter->setBrush(darkGray);
181 pen=white;
182 }
183 } else {
184 painter->setBrush(QColor(220,245,255));
185 painter->setPen(QColor(220,245,255));
186 }
187 painter->drawRect(0, 0, w, h);
188 painter->setPen(pen);
189 painter->drawText(0, 0, w, h, AlignCenter, text, -1, &rect);
190 }
191 if(rect.width()>maxCell.width()) maxCell.setWidth(rect.width());
192 if(rect.height()>maxCell.height()) maxCell.setHeight(rect.height());
193}
194
195void
196KDateTable::keyPressEvent( QKeyEvent *e )
197{
198 /*
199 // not working properly
200 if ( e->key() == Qt::Key_Prior ) {
201 if ( date.month() == 1 ) {
202 KNotifyClient::beep();
203 return;
204 }
205 int day = date.day();
206 if ( day > 27 )
207 while ( !QDate::isValid( date.year(), date.month()-1, day ) )
208 day--;
209 setDate(QDate(date.year(), date.month()-1, day));
210 return;
211 }
212 if ( e->key() == Qt::Key_Next ) {
213 if ( date.month() == 12 ) {
214 KNotifyClient::beep();
215 return;
216 }
217 int day = date.day();
218 if ( day > 27 )
219 while ( !QDate::isValid( date.year(), date.month()+1, day ) )
220 day--;
221 setDate(QDate(date.year(), date.month()+1, day));
222 return;
223 }
224 */
225 int dayoff = KGlobal::locale()->weekStartsMonday() ? 1 : 0;
226
227 int temp=firstday+date.day()-dayoff;
228 int pos = temp;
229 bool irgnore = true;
230 if ( e->state() != Qt::ControlButton ) {
231 if ( e->key() == Qt::Key_Up ) {
232 pos -= 7;
233 irgnore = false;
234 }
235 if ( e->key() == Qt::Key_Down ) {
236 pos += 7;
237 irgnore = false;
238 }
239 if ( e->key() == Qt::Key_Left ) {
240 pos--;
241 irgnore = false;
242 }
243 if ( e->key() == Qt::Key_Right ) {
244 pos++;
245 irgnore = false;
246 }
247 }
248 if ( irgnore )
249 e->ignore();
250
251 if(pos+dayoff<=firstday)
252 { // this day is in the previous month
253 KNotifyClient::beep();
254 return;
255 }
256 if(firstday+numdays<pos+dayoff)
257 { // this date is in the next month
258 KNotifyClient::beep(i18n( "Month not long enough" ));
259 return;
260 }
261
262 if ( pos == temp )
263 return;
264
265 setDate(QDate(date.year(), date.month(), pos-firstday+dayoff));
266 updateCell(temp/7+1, temp%7); // Update the previously selected cell
267 updateCell(pos/7+1, pos%7); // Update the selected cell
268 assert(QDate(date.year(), date.month(), pos-firstday+dayoff).isValid());
269
270
271}
272
273void
274KDateTable::viewportResizeEvent(QResizeEvent * e)
275{
276 QGridView::viewportResizeEvent(e);
277
278 setCellWidth(viewport()->width()/7);
279 setCellHeight(viewport()->height()/7);
280}
281
282void
283KDateTable::setFontSize(int size)
284{
285 int count;
286 QRect rect;
287 // ----- store rectangles:
288 fontsize=size;
289 QFont font = KGlobalSettings::generalFont();
290 font.setPointSize(fontsize);
291 font.setBold( true );
292 QFontMetrics metrics(font);
293
294 // ----- find largest day name:
295 maxCell.setWidth(0);
296 maxCell.setHeight(0);
297 for(count=0; count<7; ++count)
298 {
299 rect=metrics.boundingRect(KGlobal::locale()->weekDayName(count+1, true));
300 maxCell.setWidth(QMAX(maxCell.width(), rect.width()));
301 maxCell.setHeight(QMAX(maxCell.height(), rect.height()));
302 }
303 // ----- compare with a real wide number and add some space:
304 rect=metrics.boundingRect(QString::fromLatin1("88"));
305 maxCell.setWidth(QMAX(maxCell.width()+2, rect.width()));
306 maxCell.setHeight(QMAX(maxCell.height()+4, rect.height()));
307 if ( maxCell.width() * 1000 / maxCell.height() > 1900 )
308 maxCell.setHeight(maxCell.width() * 1000 / 1900 );
309}
310
311void
312KDateTable::contentsMousePressEvent(QMouseEvent *e)
313{
314 if(e->type()!=QEvent::MouseButtonPress)
315 { // the KDatePicker only reacts on mouse press events:
316 return;
317 }
318 if(!isEnabled())
319 {
320 KNotifyClient::beep();
321 return;
322 }
323
324 int dayoff = KGlobal::locale()->weekStartsMonday() ? 1 : 0;
325 // -----
326 int row, col, pos, temp;
327 QPoint mouseCoord;
328 // -----
329 mouseCoord = e->pos();
330 row=rowAt(mouseCoord.y());
331 col=columnAt(mouseCoord.x());
332 if(row<0 || col<0)
333 { // the user clicked on the frame of the table
334 return;
335 }
336 pos=7*(row-1)+col+1;
337 if(pos+dayoff<=firstday)
338 { // this day is in the previous month
339 KNotifyClient::beep();
340 return;
341 }
342 if(firstday+numdays<pos+dayoff)
343 { // this date is in the next month
344 KNotifyClient::beep();
345 return;
346 }
347 temp=firstday+date.day()-dayoff-1;
348 setDate(QDate(date.year(), date.month(), pos-firstday+dayoff));
349 updateCell(temp/7+1, temp%7); // Update the previously selected cell
350 updateCell(row, col); // Update the selected cell
351 // assert(QDate(date.year(), date.month(), pos-firstday+dayoff).isValid());
352 emit(tableClicked());
353}
354
355bool
356KDateTable::setDate(const QDate& date_)
357{
358 bool changed=false;
359 QDate temp;
360 // -----
361 if(!date_.isValid())
362 {
363 kdDebug() << "KDateTable::setDate: refusing to set invalid date." << endl;
364 return false;
365 }
366 if(date!=date_)
367 {
368 date=date_;
369 changed=true;
370 }
371 temp.setYMD(date.year(), date.month(), 1);
372 firstday=temp.dayOfWeek();
373 if(firstday==1) firstday=8;
374 numdays=date.daysInMonth();
375 if(date.month()==1)
376 { // set to december of previous year
377 temp.setYMD(date.year()-1, 12, 1);
378 } else { // set to previous month
379 temp.setYMD(date.year(), date.month()-1, 1);
380 }
381 numDaysPrevMonth=temp.daysInMonth();
382 if(changed)
383 {
384 repaintContents(false);
385 }
386 emit(dateChanged(date));
387 return true;
388}
389
390const QDate&
391KDateTable::getDate() const
392{
393 return date;
394}
395
396void KDateTable::focusInEvent( QFocusEvent *e )
397{
398 repaintContents(false);
399 QGridView::focusInEvent( e );
400}
401
402void KDateTable::focusOutEvent( QFocusEvent *e )
403{
404 repaintContents(false);
405 QGridView::focusOutEvent( e );
406}
407
408QSize
409KDateTable::sizeHint() const
410{
411 if(maxCell.height()>0 && maxCell.width()>0)
412 {
413 return QSize((maxCell.width()+2)*numCols()+2*frameWidth(),
414 (maxCell.height()+4)*numRows()+2*frameWidth());
415 } else {
416 return QSize(-1, -1);
417 }
418}
419
420KDateInternalMonthPicker::KDateInternalMonthPicker
421(int fontsize, QWidget* parent, const char* name)
422 : QGridView(parent, name),
423 result(0) // invalid
424{
425 QRect rect;
426 QFont font;
427 // -----
428 activeCol = -1;
429 activeRow = -1;
430 font=KGlobalSettings::generalFont();
431 font.setPointSize(fontsize);
432 setFont(font);
433 setHScrollBarMode(AlwaysOff);
434 setVScrollBarMode(AlwaysOff);
435 setFrameStyle(QFrame::NoFrame);
436 setNumRows(4);
437 setNumCols(3);
438 // enable to find drawing failures:
439 // setTableFlags(Tbl_clipCellPainting);
440#if 0
441 viewport()->setEraseColor(lightGray); // for consistency with the datepicker
442#endif
443 // ----- find the preferred size
444 // (this is slow, possibly, but unfortunatly it is needed here):
445 QFontMetrics metrics(font);
446 for(int i=1; i <= 12; ++i)
447 {
448 rect=metrics.boundingRect(KGlobal::locale()->monthName(i, false));
449 if(max.width()<rect.width()) max.setWidth(rect.width());
450 if(max.height()<rect.height()) max.setHeight(rect.height());
451 }
452
453}
454
455QSize
456KDateInternalMonthPicker::sizeHint() const
457{
458 return QSize((max.width()+6)*numCols()+2*frameWidth(),
459 (max.height()+6)*numRows()+2*frameWidth());
460}
461
462int
463KDateInternalMonthPicker::getResult() const
464{
465 return result;
466}
467
468void
469KDateInternalMonthPicker::setupPainter(QPainter *p)
470{
471 p->setPen(black);
472}
473
474void
475KDateInternalMonthPicker::viewportResizeEvent(QResizeEvent*)
476{
477 setCellWidth(width()/3);
478 setCellHeight(height()/4);
479}
480
481void
482KDateInternalMonthPicker::paintCell(QPainter* painter, int row, int col)
483{
484 int index;
485 QString text;
486 // ----- find the number of the cell:
487 index=3*row+col+1;
488 text=KGlobal::locale()->monthName(index, false);
489 painter->drawText(0, 0, cellWidth(), cellHeight(), AlignCenter, text);
490 if ( activeCol == col && activeRow == row )
491 painter->drawRect( 0, 0, cellWidth(), cellHeight() );
492}
493
494void
495KDateInternalMonthPicker::contentsMousePressEvent(QMouseEvent *e)
496{
497 if(!isEnabled() || e->button() != LeftButton)
498 {
499 KNotifyClient::beep();
500 return;
501 }
502 // -----
503 int row, col;
504 QPoint mouseCoord;
505 // -----
506 mouseCoord = e->pos();
507 row=rowAt(mouseCoord.y());
508 col=columnAt(mouseCoord.x());
509
510 if(row<0 || col<0)
511 { // the user clicked on the frame of the table
512 activeCol = -1;
513 activeRow = -1;
514 } else {
515 activeCol = col;
516 activeRow = row;
517 updateCell( row, col /*, false */ );
518 }
519}
520
521void
522KDateInternalMonthPicker::contentsMouseMoveEvent(QMouseEvent *e)
523{
524 if (e->state() & LeftButton)
525 {
526 int row, col;
527 QPoint mouseCoord;
528 // -----
529 mouseCoord = e->pos();
530 row=rowAt(mouseCoord.y());
531 col=columnAt(mouseCoord.x());
532 int tmpRow = -1, tmpCol = -1;
533 if(row<0 || col<0)
534 { // the user clicked on the frame of the table
535 if ( activeCol > -1 )
536 {
537 tmpRow = activeRow;
538 tmpCol = activeCol;
539 }
540 activeCol = -1;
541 activeRow = -1;
542 } else {
543 bool differentCell = (activeRow != row || activeCol != col);
544 if ( activeCol > -1 && differentCell)
545 {
546 tmpRow = activeRow;
547 tmpCol = activeCol;
548 }
549 if ( differentCell)
550 {
551 activeRow = row;
552 activeCol = col;
553 updateCell( row, col /*, false */ ); // mark the new active cell
554 }
555 }
556 if ( tmpRow > -1 ) // repaint the former active cell
557 updateCell( tmpRow, tmpCol /*, true */ );
558 }
559}
560
561void
562KDateInternalMonthPicker::contentsMouseReleaseEvent(QMouseEvent *e)
563{
564 if(!isEnabled())
565 {
566 return;
567 }
568 // -----
569 int row, col, pos;
570 QPoint mouseCoord;
571 // -----
572 mouseCoord = e->pos();
573 row=rowAt(mouseCoord.y());
574 col=columnAt(mouseCoord.x());
575 if(row<0 || col<0)
576 { // the user clicked on the frame of the table
577 emit(closeMe(0));
578 }
579 pos=3*row+col+1;
580 result=pos;
581 emit(closeMe(1));
582}
583
584
585
586KDateInternalYearSelector::KDateInternalYearSelector
587(int fontsize, QWidget* parent, const char* name)
588 : QLineEdit(parent, name),
589 val(new QIntValidator(this)),
590 result(0)
591{
592 QFont font;
593 // -----
594 font=KGlobalSettings::generalFont();
595 font.setPointSize(fontsize);
596 setFont(font);
597#if 0
598 setFrameStyle(QFrame::NoFrame);
599#endif
600 // we have to respect the limits of QDate here, I fear:
601 val->setRange(0, 8000);
602 setValidator(val);
603 connect(this, SIGNAL(returnPressed()), SLOT(yearEnteredSlot()));
604}
605
606void
607KDateInternalYearSelector::yearEnteredSlot()
608{
609 bool ok;
610 int year;
611 QDate date;
612 // ----- check if this is a valid year:
613 year=text().toInt(&ok);
614 if(!ok)
615 {
616 KNotifyClient::beep();
617 return;
618 }
619 date.setYMD(year, 1, 1);
620 if(!date.isValid())
621 {
622 KNotifyClient::beep();
623 return;
624 }
625 result=year;
626 emit(closeMe(1));
627}
628
629int
630KDateInternalYearSelector::getYear()
631{
632 return result;
633}
634
635void
636KDateInternalYearSelector::setYear(int year)
637{
638 QString temp;
639 // -----
640 temp.setNum(year);
641 setText(temp);
642}
643
644KPopupFrame::KPopupFrame(QWidget* parent, const char* name)
645 : QFrame(parent, name, WType_Popup),
646 result(0), // rejected
647 main(0)
648{
649 setFrameStyle(QFrame::Box|QFrame::Raised);
650 setMidLineWidth(2);
651}
652
653void
654KPopupFrame::keyPressEvent(QKeyEvent* e)
655{
656 if(e->key()==Key_Escape)
657 {
658 result=0; // rejected
659 qApp->exit_loop();
660 }
661}
662
663void
664KPopupFrame::close(int r)
665{
666 result=r;
667 qApp->exit_loop();
668}
669
670void
671KPopupFrame::setMainWidget(QWidget* m)
672{
673 main=m;
674 if(main!=0)
675 {
676 resize(main->width()+2*frameWidth(), main->height()+2*frameWidth());
677 }
678}
679
680void
681KPopupFrame::resizeEvent(QResizeEvent*)
682{
683 if(main!=0)
684 {
685 main->setGeometry(frameWidth(), frameWidth(),
686 width()-2*frameWidth(), height()-2*frameWidth());
687 }
688}
689
690void
691KPopupFrame::popup(const QPoint &pos)
692{
693 // Make sure the whole popup is visible.
694 QRect d = QApplication::desktop()->frameGeometry();
695 int x = pos.x();
696 int y = pos.y();
697 int w = width();
698 int h = height();
699 if (x+w > d.x()+d.width())
700 x = d.width() - w;
701 if (y+h > d.y()+d.height())
702 y = d.height() - h;
703 if (x < d.x())
704 x = 0;
705 if (y < d.y())
706 y = 0;
707
708 // Pop the thingy up.
709 move(x, y);
710 show();
711}
712
713int
714KPopupFrame::exec(QPoint pos)
715{
716 popup(pos);
717 repaint();
718 qApp->enter_loop();
719 hide();
720 return result;
721}
722
723int
724KPopupFrame::exec(int x, int y)
725{
726 return exec(QPoint(x, y));
727}
728
729void KPopupFrame::virtual_hook( int, void* )
730{ /*BASE::virtual_hook( id, data );*/ }
731
732void KDateTable::virtual_hook( int, void* )
733{ /*BASE::virtual_hook( id, data );*/ }
734
735//#include "kdatetbl.moc"
diff --git a/microkde/kdatetbl.h b/microkde/kdatetbl.h
new file mode 100644
index 0000000..df7b7ef
--- a/dev/null
+++ b/microkde/kdatetbl.h
@@ -0,0 +1,308 @@
1/* -*- C++ -*-
2 This file is part of the KDE libraries
3 Copyright (C) 1997 Tim D. Gilman (tdgilman@best.org)
4 (C) 1998-2001 Mirko Boehm (mirko@kde.org)
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20#ifndef KDATETBL_H
21#define KDATETBL_H
22
23#include <qvalidator.h>
24#include <qgridview.h>
25#include <qlineedit.h>
26#include <qdatetime.h>
27
28/**
29* A table containing month names. It is used to pick a month directly.
30* @internal
31* @version $Id$
32* @author Tim Gilman, Mirko Boehm
33*/
34class KDateInternalMonthPicker : public QGridView
35{
36 Q_OBJECT
37protected:
38 /**
39 * Store the month that has been clicked [1..12].
40 */
41 int result;
42 /**
43 * the cell under mouse cursor when LBM is pressed
44 */
45 short int activeCol;
46 short int activeRow;
47 /**
48 * Contains the largest rectangle needed by the month names.
49 */
50 QRect max;
51signals:
52 /**
53 * This is send from the mouse click event handler.
54 */
55 void closeMe(int);
56public:
57 /**
58 * The constructor.
59 */
60 KDateInternalMonthPicker(int fontsize, QWidget* parent, const char* name=0);
61 /**
62 * The size hint.
63 */
64 QSize sizeHint() const;
65 /**
66 * Return the result. 0 means no selection (reject()), 1..12 are the
67 * months.
68 */
69 int getResult() const;
70protected:
71 /**
72 * Set up the painter.
73 */
74 void setupPainter(QPainter *p);
75 /**
76 * The resize event.
77 */
78 void viewportResizeEvent(QResizeEvent*);
79 /**
80 * Paint a cell. This simply draws the month names in it.
81 */
82 virtual void paintCell(QPainter* painter, int row, int col);
83 /**
84 * Catch mouse click and move events to paint a rectangle around the item.
85 */
86 void contentsMousePressEvent(QMouseEvent *e);
87 void contentsMouseMoveEvent(QMouseEvent *e);
88 /**
89 * Emit monthSelected(int) when a cell has been released.
90 */
91 void contentsMouseReleaseEvent(QMouseEvent *e);
92
93private:
94 class KDateInternalMonthPrivate;
95 KDateInternalMonthPrivate *d;
96};
97
98/** Year selection widget.
99* @internal
100* @version $Id$
101* @author Tim Gilman, Mirko Boehm
102*/
103class KDateInternalYearSelector : public QLineEdit
104{
105 Q_OBJECT
106protected:
107 QIntValidator *val;
108 int result;
109public slots:
110 void yearEnteredSlot();
111signals:
112 void closeMe(int);
113public:
114 KDateInternalYearSelector(int fontsize,
115 QWidget* parent=0,
116 const char* name=0);
117 int getYear();
118 void setYear(int year);
119
120private:
121 class KDateInternalYearPrivate;
122 KDateInternalYearPrivate *d;
123};
124
125/**
126 * Frame with popup menu behaviour.
127 * @author Tim Gilman, Mirko Boehm
128 * @version $Id$
129 */
130class KPopupFrame : public QFrame
131{
132 Q_OBJECT
133protected:
134 /**
135 * The result. It is returned from exec() when the popup window closes.
136 */
137 int result;
138 /**
139 * Catch key press events.
140 */
141 void keyPressEvent(QKeyEvent* e);
142 /**
143 * The only subwidget that uses the whole dialog window.
144 */
145 QWidget *main;
146public slots:
147 /**
148 * Close the popup window. This is called from the main widget, usually.
149 * @p r is the result returned from exec().
150 */
151 void close(int r);
152public:
153 /**
154 * The contructor. Creates a dialog without buttons.
155 */
156 KPopupFrame(QWidget* parent=0, const char* name=0);
157 /**
158 * Set the main widget. You cannot set the main widget from the constructor,
159 * since it must be a child of the frame itselfes.
160 * Be careful: the size is set to the main widgets size. It is up to you to
161 * set the main widgets correct size before setting it as the main
162 * widget.
163 */
164 void setMainWidget(QWidget* m);
165 /**
166 * The resize event. Simply resizes the main widget to the whole
167 * widgets client size.
168 */
169 void resizeEvent(QResizeEvent*);
170 /**
171 * Open the popup window at position pos.
172 */
173 void popup(const QPoint &pos);
174 /**
175 * Execute the popup window.
176 */
177 int exec(QPoint p);
178 /**
179 * Dito.
180 */
181 int exec(int x, int y);
182
183private:
184
185 virtual bool close(bool alsoDelete) { return QFrame::close(alsoDelete); }
186protected:
187 virtual void virtual_hook( int id, void* data );
188private:
189 class KPopupFramePrivate;
190 KPopupFramePrivate *d;
191};
192
193/**
194* Validates user-entered dates.
195*/
196class KDateValidator : public QValidator
197{
198public:
199 KDateValidator(QWidget* parent=0, const char* name=0);
200 virtual State validate(QString&, int&) const;
201 virtual void fixup ( QString & input ) const;
202 State date(const QString&, QDate&) const;
203};
204
205/**
206 * Date selection table.
207 * This is a support class for the KDatePicker class. It just
208 * draws the calender table without titles, but could theoretically
209 * be used as a standalone.
210 *
211 * When a date is selected by the user, it emits a signal:
212 * dateSelected(QDate)
213 *
214 * @internal
215 * @version $Id$
216 * @author Tim Gilman, Mirko Boehm
217 */
218class KDateTable : public QGridView
219{
220 Q_OBJECT
221public:
222 /**
223 * The constructor.
224 */
225 KDateTable(QWidget *parent=0,
226 QDate date=QDate::currentDate(),
227 const char* name=0, WFlags f=0);
228 /**
229 * Returns a recommended size for the widget.
230 * To save some time, the size of the largest used cell content is
231 * calculated in each paintCell() call, since all calculations have
232 * to be done there anyway. The size is stored in maxCell. The
233 * sizeHint() simply returns a multiple of maxCell.
234 */
235 virtual QSize sizeHint() const;
236 /**
237 * Set the font size of the date table.
238 */
239 void setFontSize(int size);
240 /**
241 * Select and display this date.
242 */
243 bool setDate(const QDate&);
244 const QDate& getDate() const;
245
246
247protected:
248 /**
249 * Paint a cell.
250 */
251 virtual void paintCell(QPainter*, int, int);
252 /**
253 * Handle the resize events.
254 */
255 virtual void viewportResizeEvent(QResizeEvent *);
256 /**
257 * React on mouse clicks that select a date.
258 */
259 virtual void contentsMousePressEvent(QMouseEvent *);
260 virtual void keyPressEvent( QKeyEvent *e );
261 virtual void focusInEvent( QFocusEvent *e );
262 virtual void focusOutEvent( QFocusEvent *e );
263 /**
264 * The font size of the displayed text.
265 */
266 int fontsize;
267 /**
268 * The currently selected date.
269 */
270 QDate date;
271 /**
272 * The day of the first day in the month [1..7].
273 */
274 int firstday;
275 /**
276 * The number of days in the current month.
277 */
278 int numdays;
279 /**
280 * The number of days in the previous month.
281 */
282 int numDaysPrevMonth;
283 /**
284 * unused
285 */
286 bool unused_hasSelection;
287 /**
288 * Save the size of the largest used cell content.
289 */
290 QRect maxCell;
291signals:
292 /**
293 * The selected date changed.
294 */
295 void dateChanged(QDate);
296 /**
297 * A date has been selected by clicking on the table.
298 */
299 void tableClicked();
300
301protected:
302 virtual void virtual_hook( int id, void* data );
303private:
304 class KDateTablePrivate;
305 KDateTablePrivate *d;
306};
307
308#endif // KDATETBL_H
diff --git a/microkde/kdebug.h b/microkde/kdebug.h
new file mode 100644
index 0000000..bb9cfe3
--- a/dev/null
+++ b/microkde/kdebug.h
@@ -0,0 +1,92 @@
1#ifndef MINIKDE_KDEBUG_H
2#define MINIKDE_KDEBUG_H
3
4#include <stdio.h>
5
6#include <qstring.h>
7
8
9
10class kdbgstream;
11typedef kdbgstream & (*KDBGFUNC)(kdbgstream &); // manipulator function
12
13class kdbgstream {
14 public:
15 kdbgstream(unsigned int _area, unsigned int _level, bool _print = true) :
16 area(_area), level(_level), print( _print ) { print = false; }
17 /* kdbgstream(const char * initialString, unsigned int _area, unsigned int _level, bool _print = false) :
18 output(QString::fromLatin1(initialString)), area(_area), level(_level), print(_print) { print = false; }*/
19 ~kdbgstream()
20 {
21 // if (!output.isEmpty()) {
22 // fprintf(stderr,"ASSERT: debug output not ended with \\n\n");
23 //*this << "\n";
24 //}
25 }
26 kdbgstream &operator<<(bool) {
27
28 return *this;
29 }
30 kdbgstream &operator<<(short) {
31
32 return *this;
33 }
34 kdbgstream &operator<<(unsigned short) {
35
36 return *this;
37 }
38 kdbgstream &operator<<(char) {
39
40 return *this;
41 }
42 kdbgstream &operator<<(unsigned char) {
43
44 return *this;
45 }
46
47 kdbgstream &operator<<(int) {
48
49 return *this;
50 }
51 kdbgstream &operator<<(unsigned int) {
52
53 return *this;
54 }
55 kdbgstream &operator<<(long) {
56 return *this;
57 }
58 kdbgstream &operator<<(unsigned long) {
59 return *this;
60 }
61 kdbgstream &operator<<(const QString&) {
62 return *this;
63 }
64 kdbgstream &operator<<(const char*) {
65 return *this;
66 }
67 kdbgstream &operator<<(const QCString&) {
68 return *this;
69 }
70 kdbgstream& operator<<(KDBGFUNC f) {
71 return (*f)(*this);
72 }
73 kdbgstream& operator<<(double) {
74 if (!print) return *this;
75 return *this;
76 }
77 void flush() {
78 return;
79 }
80 private:
81 QString output;
82 unsigned int area, level;
83 bool print;
84};
85
86inline kdbgstream &endl( kdbgstream &s) { s << "\n"; return s; }
87
88inline kdbgstream kdDebug(int area = 0) { return kdbgstream(area, 0); }
89inline kdbgstream kdWarning(int area = 0) { return kdbgstream(area, 0); }
90inline kdbgstream kdError(int area = 0) { return kdbgstream(area, 0); }
91
92#endif
diff --git a/microkde/kdecore/kcatalogue.cpp b/microkde/kdecore/kcatalogue.cpp
new file mode 100644
index 0000000..97ac326
--- a/dev/null
+++ b/microkde/kdecore/kcatalogue.cpp
@@ -0,0 +1,131 @@
1/* This file is part of the KDE libraries
2 Copyright (c) 2001 Hans Petter Bieker <bieker@kde.org>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA.
18*/
19
20//US #include <config.h>
21
22#include <qfile.h>
23
24#include <kdebug.h>
25
26#include "kcatalogue.h"
27
28char *k_nl_find_msg(struct kde_loaded_l10nfile *domain_file,
29 const char *msgid);
30void k_nl_unload_domain (struct loaded_domain *domain);
31
32#ifndef KDE_USE_FINAL // with --enable-final, we're getting this from libintl.cpp
33struct kde_loaded_l10nfile
34{
35 const char *filename;
36 int decided;
37
38 const void *data;
39
40 kde_loaded_l10nfile() : filename(0), decided(0), data(0) {}
41};
42#endif
43
44class KCataloguePrivate
45{
46public:
47 QString name;
48
49 kde_loaded_l10nfile domain;
50};
51
52KCatalogue::KCatalogue(const QString & name)
53 : d( new KCataloguePrivate )
54{
55 d->name = name;
56}
57
58KCatalogue::KCatalogue(const KCatalogue & rhs)
59 : d( new KCataloguePrivate )
60{
61 *this = rhs;
62}
63
64KCatalogue & KCatalogue::operator=(const KCatalogue & rhs)
65{
66 d->name = rhs.d->name;
67 setFileName( rhs.fileName() );
68
69 return *this;
70}
71
72KCatalogue::~KCatalogue()
73{
74 doUnload();
75
76 delete d;
77}
78
79QString KCatalogue::name() const
80{
81 return d->name;
82}
83
84void KCatalogue::setFileName( const QString & fileName )
85{
86 // nothing to do if the file name is already the same
87 if ( this->fileName() == fileName ) return;
88
89 doUnload();
90
91 QCString newFileName = QFile::encodeName( fileName );
92
93 if ( !fileName.isEmpty() )
94 {
95 // set file name
96 char *filename = new char[ newFileName.length() + 1 ];
97 ::qstrcpy( filename, newFileName );
98 d->domain.filename = filename;
99 }
100}
101
102QString KCatalogue::fileName() const
103{
104 return QFile::decodeName( d->domain.filename );
105}
106
107const char * KCatalogue::translate(const char * msgid) const
108{
109 qDebug("KCatalogue::translate has to be fixed %s",msgid );
110//US return ::k_nl_find_msg( &d->domain, msgid );
111 return msgid;
112
113}
114
115void KCatalogue::doUnload()
116{
117 // use gettext's unloader
118 if ( d->domain.data )
119 {
120//US ::k_nl_unload_domain( (struct loaded_domain *)d->domain.data );
121 qDebug("KCatalogue::doUnload has to be fixed" );
122
123 }
124 d->domain.data = 0;
125
126 // free name
127 delete [] const_cast<char *>(d->domain.filename);
128 d->domain.filename = 0;
129
130 d->domain.decided = 0;
131}
diff --git a/microkde/kdecore/kcatalogue.h b/microkde/kdecore/kcatalogue.h
new file mode 100644
index 0000000..e229cc8
--- a/dev/null
+++ b/microkde/kdecore/kcatalogue.h
@@ -0,0 +1,104 @@
1/* This file is part of the KDE libraries
2 Copyright (c) 2001 Hans Petter Bieker <bieker@kde.org>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA.
18*/
19
20#ifndef KCATALOGUE_H
21#define KCATALOGUE_H
22
23#include <qstring.h>
24
25struct kde_loaded_l10nfile;
26
27class KCataloguePrivate;
28
29/**
30 * This class abstracts a gettext message catalogue. It will take care of
31 * opening the file and reading the catalogue.
32 *
33 * @see KLocale
34 */
35//REVISED: hausmann
36class KCatalogue
37{
38public:
39 /**
40 * Constructor.
41 *
42 * @param name The name of the catalogue
43 */
44 explicit KCatalogue(const QString & name = QString::null);
45
46 /**
47 * Copy constructor.
48 */
49 KCatalogue(const KCatalogue & rhs);
50
51 /**
52 * Assignment operator.
53 */
54 KCatalogue & operator = ( const KCatalogue & rhs);
55
56 /**
57 * Destructor.
58 */
59 virtual ~KCatalogue();
60
61 /**
62 * Returns the name of the catalogue.
63 *
64 * @return The name of the catalogue
65 */
66 QString name() const;
67
68 /**
69 * Changes the current file name.
70 *
71 * @param fileName The new file name
72 */
73
74 void setFileName( const QString & fileName );
75
76 /**
77 * Retrieves a translation of the specified message id.
78 *
79 * Do not pass 0 or "" strings as message ids.
80 *
81 * @param msgid The message id
82 *
83 * @return The translated message, in utf8 encoding, or 0 if not found
84 */
85 const char * translate( const char * msgid ) const;
86
87private:
88 /**
89 * @internal Retrieves the current file name.
90 *
91 * @return The current file name, if any.
92 */
93 QString fileName() const;
94
95 /**
96 * @internal Unloads the current file.
97 */
98 void doUnload();
99
100private:
101 KCataloguePrivate * d;
102};
103
104#endif
diff --git a/microkde/kdecore/kconfigbase.h b/microkde/kdecore/kconfigbase.h
new file mode 100644
index 0000000..7e56d11
--- a/dev/null
+++ b/microkde/kdecore/kconfigbase.h
@@ -0,0 +1,102 @@
1/*
2 This file is part of the KDE libraries
3 Copyright (c) 1999 Preston Brown <pbrown@kde.org>
4 Copyright (c) 1997 Matthias Kalle Dalheimer <kalle@kde.org>
5 Copyright (c) 2001 Waldo Bastian <bastian@kde.org>
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Library General Public
9 License as published by the Free Software Foundation; either
10 version 2 of the License, or (at your option) any later version.
11
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Library General Public License for more details.
16
17 You should have received a copy of the GNU Library General Public License
18 along with this library; see the file COPYING.LIB. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.
21*/
22
23// $Id$
24
25#ifndef _KCONFIGBASE_H
26#define _KCONFIGBASE_H
27
28#include "kconfig.h"
29
30/**
31 * Helper class to facilitate working with @ref KConfig / @ref KSimpleConfig
32 * groups.
33 *
34 * Careful programmers always set the group of a
35 * @ref KConfig @ref KSimpleConfig object to the group they want to read from
36 * and set it back to the old one of afterwards. This is usually
37 * written as:
38 * <pre>
39 *
40 * QString oldgroup config->group();
41 * config->setGroup( "TheGroupThatIWant" );
42 * ...
43 * config->writeEntry( "Blah", "Blubb" );
44 *
45 * config->setGroup( oldgroup );
46 * </pre>
47 *
48 * In order to facilitate this task, you can use
49 * KConfigGroupSaver. Simply construct such an object ON THE STACK
50 * when you want to switch to a new group. Then, when the object goes
51 * out of scope, the group will automatically be restored. If you
52 * want to use several different groups within a function or method,
53 * you can still use KConfigGroupSaver: Simply enclose all work with
54 * one group (including the creation of the KConfigGroupSaver object)
55 * in one block.
56 *
57 * @author Matthias Kalle Dalheimer <kalle@kde.org>
58 * @version $Id$
59 * @see KConfigBase, KConfig, KSimpleConfig
60 * @short Helper class for easier use of KConfig/KSimpleConfig groups
61 */
62//US I converted the class in a way that it can be used with KConfig objects of microkde
63
64class KConfigGroupSaver
65{
66public:
67 /**
68 * Constructor. You pass a pointer to the KConfigBase-derived
69 * object you want to work with and a string indicating the _new_
70 * group.
71 *
72 * @param config The KConfigBase-derived object this
73 * KConfigGroupSaver works on.
74 * @param group The new group that the config object should switch to.
75 */
76 KConfigGroupSaver( KConfig* config, QString group )
77 /* KDE 4 : make the second parameter const QString & */
78 : _config(config), _oldgroup(config->group())
79 { _config->setGroup( group ); }
80
81 KConfigGroupSaver( KConfig* config, const char *group )
82 : _config(config), _oldgroup(config->group())
83 { _config->setGroup( group ); }
84
85 KConfigGroupSaver( KConfig* config, const QCString &group )
86 : _config(config), _oldgroup(config->group())
87 { _config->setGroup( group ); }
88
89 ~KConfigGroupSaver() { _config->setGroup( _oldgroup ); }
90
91 KConfig* config() { return _config; };
92
93private:
94 KConfig* _config;
95 QString _oldgroup;
96
97 KConfigGroupSaver(const KConfigGroupSaver&);
98 KConfigGroupSaver& operator=(const KConfigGroupSaver&);
99
100};
101
102#endif
diff --git a/microkde/kdecore/klibloader.cpp b/microkde/kdecore/klibloader.cpp
new file mode 100644
index 0000000..1410308
--- a/dev/null
+++ b/microkde/kdecore/klibloader.cpp
@@ -0,0 +1,626 @@
1/* This file is part of the KDE libraries
2 Copyright (C) 1999 Torben Weis <weis@kde.org>
3 Copyright (C) 2000 Michael Matz <matz@kde.org>
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License version 2 as published by the Free Software Foundation.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA.
18*/
19//US #include <config.h>
20#include <qclipboard.h>
21#include <qfile.h>
22#include <qtimer.h>
23#include <qobjectdict.h>
24#include <qwidgetlist.h>
25#include <qwidget.h>
26
27#include "kapplication.h"
28#include "klibloader.h"
29#include "kstandarddirs.h"
30#include "kdebug.h"
31#include "klocale.h"
32
33//US #include "ltdl.h"
34
35//US do everything through qlibrary
36#ifndef DESKTOP_VERSION
37#include <qpe/qpeapplication.h>
38#include <qtopia/qlibrary.h>
39#endif
40
41/*US
42#ifdef Q_WS_X11
43#include <X11/Xlib.h>
44#include <X11/Xatom.h>
45#endif
46*/
47template class QAsciiDict<KLibrary>;
48
49#include <stdlib.h> //getenv
50
51/*US
52#if HAVE_DLFCN_H
53# include <dlfcn.h>
54#endif
55
56#ifdef RTLD_GLOBAL
57# define LT_GLOBAL RTLD_GLOBAL
58#else
59# ifdef DL_GLOBAL
60# define LT_GLOBAL DL_GLOBAL
61# endif
62#endif
63#ifndef LT_GLOBAL
64# define LT_GLOBAL 0
65#endif
66*/
67
68/*US
69extern "C" {
70extern int lt_dlopen_flag;
71}
72*/
73
74KLibFactory::KLibFactory( QObject* parent, const char* name )
75 : QObject( parent, name )
76{
77}
78
79KLibFactory::~KLibFactory()
80{
81// kdDebug(150) << "Deleting KLibFactory " << this << endl;
82}
83
84QObject* KLibFactory::create( QObject* parent, const char* name, const char* classname, const QStringList &args )
85{
86 QObject* obj = createObject( parent, name, classname, args );
87 if ( obj )
88 emit objectCreated( obj );
89 return obj;
90}
91
92
93QObject* KLibFactory::createObject( QObject*, const char*, const char*, const QStringList &)
94{
95 return 0;
96}
97
98
99// -----------------------------------------------
100
101//US KLibrary::KLibrary( const QString& libname, const QString& filename, void * handle )
102KLibrary::KLibrary( const QString& libname, const QString& filename, QLibrary* handle )
103{
104 /* Make sure, we have a KLibLoader */
105 (void) KLibLoader::self();
106 m_libname = libname;
107 m_filename = filename;
108 m_handle = handle;
109 m_factory = 0;
110 m_timer = 0;
111}
112
113KLibrary::~KLibrary()
114{
115// kdDebug(150) << "Deleting KLibrary " << this << " " << m_libname << endl;
116 if ( m_timer && m_timer->isActive() )
117 m_timer->stop();
118
119 // If any object is remaining, delete
120 if ( m_objs.count() > 0 )
121 {
122 QPtrListIterator<QObject> it( m_objs );
123 for ( ; it.current() ; ++it )
124 {
125 kdDebug(150) << "Factory still has object " << it.current() << " " << it.current()->name () << " Library = " << m_libname << endl;
126 disconnect( it.current(), SIGNAL( destroyed() ),
127 this, SLOT( slotObjectDestroyed() ) );
128 }
129 m_objs.setAutoDelete(true);
130 m_objs.clear();
131 }
132
133 if ( m_factory ) {
134 //kdDebug(150) << " ... deleting the factory " << m_factory << endl;
135 delete m_factory;
136 }
137}
138
139QString KLibrary::name() const
140{
141 return m_libname;
142}
143
144QString KLibrary::fileName() const
145{
146 return m_filename;
147}
148
149KLibFactory* KLibrary::factory()
150{
151 if ( m_factory )
152 return m_factory;
153
154 QCString symname;
155 symname.sprintf("init_%s", name().latin1() );
156
157 void* sym = symbol( symname );
158 if ( !sym )
159 {
160 kdWarning(150) << "KLibrary: The library " << name() << " does not offer an init_" << name() << " function" << endl;
161 return 0;
162 }
163
164 typedef KLibFactory* (*t_func)();
165 t_func func = (t_func)sym;
166 m_factory = func();
167
168 if( !m_factory )
169 {
170 kdWarning(150) << "KLibrary: The library " << name() << " does not offer a KDE compatible factory" << endl;
171 return 0;
172 }
173
174 connect( m_factory, SIGNAL( objectCreated( QObject * ) ),
175 this, SLOT( slotObjectCreated( QObject * ) ) );
176
177 return m_factory;
178}
179
180void* KLibrary::symbol( const char* symname ) const
181{
182//US void* sym = lt_dlsym( (lt_dlhandle) m_handle, symname );
183 void* sym = m_handle->resolve( symname );
184 if ( !sym )
185 {
186//US kdWarning(150) << "KLibrary: " << lt_dlerror() << endl;
187 kdWarning(150) << "KLibrary: " << m_libname << ", symbol:" << symname << " not found " << endl;
188 return 0;
189 }
190
191 return sym;
192}
193
194bool KLibrary::hasSymbol( const char* symname ) const
195{
196//US void* sym = lt_dlsym( (lt_dlhandle) m_handle, symname );
197 void* sym = m_handle->resolve( symname );
198 return (sym != 0L );
199}
200
201void KLibrary::unload() const
202{
203 if (KLibLoader::s_self)
204 KLibLoader::s_self->unloadLibrary(QFile::encodeName(name()));
205}
206
207void KLibrary::slotObjectCreated( QObject *obj )
208{
209 if ( !obj )
210 return;
211
212 if ( m_timer && m_timer->isActive() )
213 m_timer->stop();
214
215 if ( m_objs.containsRef( obj ) )
216 return; // we know this object already
217
218 connect( obj, SIGNAL( destroyed() ),
219 this, SLOT( slotObjectDestroyed() ) );
220
221 m_objs.append( obj );
222}
223
224void KLibrary::slotObjectDestroyed()
225{
226 m_objs.removeRef( sender() );
227
228 if ( m_objs.count() == 0 )
229 {
230// kdDebug(150) << "KLibrary: shutdown timer for " << name() << " started!"
231// << endl;
232
233 if ( !m_timer )
234 {
235 m_timer = new QTimer( this, "klibrary_shutdown_timer" );
236 connect( m_timer, SIGNAL( timeout() ),
237 this, SLOT( slotTimeout() ) );
238 }
239
240 // as long as it's not stable make the timeout short, for debugging
241 // pleasure (matz)
242 //m_timer->start( 1000*60, true );
243 m_timer->start( 1000*10, true );
244 }
245}
246
247void KLibrary::slotTimeout()
248{
249 if ( m_objs.count() != 0 )
250 return;
251
252 /* Don't go through KLibLoader::unloadLibrary(), because that uses the
253 ref counter, but this timeout means to unconditionally close this library
254 The destroyed() signal will take care to remove us from all lists.
255 */
256 delete this;
257}
258
259// -------------------------------------------------
260
261/* This helper class is needed, because KLibraries can go away without
262 being unloaded. So we need some info about KLibraries even after its
263 death. */
264class KLibWrapPrivate
265{
266public:
267//US KLibWrapPrivate(KLibrary *l, lt_dlhandle h);
268 KLibWrapPrivate(KLibrary *l, QLibrary* h);
269
270 KLibrary *lib;
271 enum {UNKNOWN, UNLOAD, DONT_UNLOAD} unload_mode;
272 int ref_count;
273//US lt_dlhandle handle;
274 QLibrary *handle;
275 QString name;
276 QString filename;
277};
278
279//US KLibWrapPrivate::KLibWrapPrivate(KLibrary *l, lt_dlhandle h)
280KLibWrapPrivate::KLibWrapPrivate(KLibrary *l, QLibrary* h)
281 : lib(l), ref_count(1), handle(h), name(l->name()), filename(l->fileName())
282{
283 unload_mode = UNKNOWN;
284/*US
285 if (lt_dlsym(handle, "__kde_do_not_unload") != 0) {
286// kdDebug(150) << "Will not unload " << name << endl;
287 unload_mode = DONT_UNLOAD;
288 } else if (lt_dlsym(handle, "__kde_do_unload") != 0) {
289 unload_mode = UNLOAD;
290 }
291*/
292//US use instead:
293 if (h->resolve("__kde_do_not_unload") != 0) {
294// kdDebug(150) << "Will not unload " << name << endl;
295 unload_mode = DONT_UNLOAD;
296 } else if (h->resolve("__kde_do_unload") != 0) {
297 unload_mode = UNLOAD;
298 }
299}
300
301class KLibLoaderPrivate
302{
303public:
304 QPtrList<KLibWrapPrivate> loaded_stack;
305 QPtrList<KLibWrapPrivate> pending_close;
306 enum {UNKNOWN, UNLOAD, DONT_UNLOAD} unload_mode;
307
308 QString errorMessage;
309};
310
311KLibLoader* KLibLoader::s_self = 0;
312
313KLibLoader* KLibLoader::self()
314{
315 if ( !s_self )
316 s_self = new KLibLoader;
317 return s_self;
318}
319
320void KLibLoader::cleanUp()
321{
322 if ( !s_self )
323 return;
324
325 delete s_self;
326 s_self = 0;
327}
328
329KLibLoader::KLibLoader( QObject* parent, const char* name )
330 : QObject( parent, name )
331{
332 s_self = this;
333 d = new KLibLoaderPrivate;
334//US lt_dlinit();
335 d->unload_mode = KLibLoaderPrivate::UNKNOWN;
336 if (getenv("KDE_NOUNLOAD") != 0)
337 d->unload_mode = KLibLoaderPrivate::DONT_UNLOAD;
338 else if (getenv("KDE_DOUNLOAD") != 0)
339 d->unload_mode = KLibLoaderPrivate::UNLOAD;
340 d->loaded_stack.setAutoDelete( true );
341}
342
343KLibLoader::~KLibLoader()
344{
345// kdDebug(150) << "Deleting KLibLoader " << this << " " << name() << endl;
346
347 QAsciiDictIterator<KLibWrapPrivate> it( m_libs );
348 for (; it.current(); ++it )
349 {
350 kdDebug(150) << "The KLibLoader contains the library " << it.current()->name
351 << " (" << it.current()->lib << ")" << endl;
352 d->pending_close.append(it.current());
353 }
354
355 close_pending(0);
356
357 delete d;
358}
359
360//static
361QString KLibLoader::findLibrary( const char * name/*US , const KInstance * instance*/ )
362{
363 QCString libname( name );
364
365 // only append ".la" if there is no extension
366 // this allows to load non-libtool libraries as well
367 // (mhk, 20000228)
368 int pos = libname.findRev('/');
369 if (pos < 0)
370 pos = 0;
371 if (libname.find('.', pos) < 0)
372 libname += ".la";
373
374 // only look up the file if it is not an absolute filename
375 // (mhk, 20000228)
376 QString libfile;
377 if (libname[0] == '/')
378 libfile = libname;
379 else
380 {
381//US libfile = instance->dirs()->findResource( "module", libname );
382 libfile = KGlobal::dirs()->findResource( "module", libname );
383 if ( libfile.isEmpty() )
384 {
385//US libfile = instance->dirs()->findResource( "lib", libname );
386 libfile = KGlobal::dirs()->findResource( "lib", libname );
387#ifndef NDEBUG
388 if ( !libfile.isEmpty() && libname.left(3) == "lib" ) // don't warn for kdeinit modules
389 kdDebug(150) << "library " << libname << " not found under 'module' but under 'lib'" << endl;
390#endif
391 }
392 if ( libfile.isEmpty() )
393 {
394#ifndef NDEBUG
395 kdDebug(150) << "library=" << libname << ": No file names " << libname.data() << " found in paths." << endl;
396#endif
397 self()->d->errorMessage = i18n("Library files for \"%1\" not found in paths").arg(libname);
398 }
399 else
400 self()->d->errorMessage = QString::null;
401 }
402 return libfile;
403}
404
405
406KLibrary* KLibLoader::globalLibrary( const char *name )
407{
408KLibrary *tmp;
409/*US
410int olt_dlopen_flag = lt_dlopen_flag;
411
412 lt_dlopen_flag |= LT_GLOBAL;
413 kdDebug(150) << "Loading the next library global with flag "
414 << lt_dlopen_flag
415 << "." << endl;
416*/
417 tmp = library(name);
418/*US
419 lt_dlopen_flag = olt_dlopen_flag;
420*/
421return tmp;
422}
423
424
425KLibrary* KLibLoader::library( const char *name )
426{
427 if (!name)
428 return 0;
429
430 KLibWrapPrivate* wrap = m_libs[name];
431 if (wrap) {
432 /* Nothing to do to load the library. */
433 wrap->ref_count++;
434 return wrap->lib;
435 }
436
437 /* Test if this library was loaded at some time, but got
438 unloaded meanwhile, whithout being dlclose()'ed. */
439 QPtrListIterator<KLibWrapPrivate> it(d->loaded_stack);
440 for (; it.current(); ++it) {
441 if (it.current()->name == name)
442 wrap = it.current();
443 }
444
445 if (wrap) {
446 d->pending_close.removeRef(wrap);
447 if (!wrap->lib) {
448 /* This lib only was in loaded_stack, but not in m_libs. */
449 wrap->lib = new KLibrary( name, wrap->filename, wrap->handle );
450 }
451 wrap->ref_count++;
452 } else {
453 QString libfile = findLibrary( name );
454 if ( libfile.isEmpty() )
455 return 0;
456
457 const QString & qpeDir = QPEApplication::qpeDir();
458 libfile = qpeDir + libfile;
459//US QLibrary *lib = new QLibrary( qpeDir + "/plugins/korganizer/libopiekabc.so", QLibrary::Immediately );
460 QLibrary *qlib = new QLibrary( libfile.latin1(), QLibrary::Immediately );
461
462//US lt_dlhandle handle = lt_dlopen( libfile.latin1() );
463//US if ( !handle )
464 if ( !qlib )
465 {
466//US const char* errmsg = lt_dlerror();
467 char* errmsg;
468 sprintf(errmsg, "KLibLoader::library could not load library: %s", libfile.latin1());
469 qDebug(errmsg);
470
471 if(errmsg)
472 d->errorMessage = QString::fromLatin1(errmsg);
473 else
474 d->errorMessage = QString::null;
475 kdWarning(150) << "library=" << name << ": file=" << libfile << ": " << d->errorMessage << endl;
476 return 0;
477 }
478 else
479 d->errorMessage = QString::null;
480
481 KLibrary *lib = new KLibrary( name, libfile, qlib );
482 wrap = new KLibWrapPrivate(lib, qlib);
483 d->loaded_stack.prepend(wrap);
484 }
485 m_libs.insert( name, wrap );
486
487 connect( wrap->lib, SIGNAL( destroyed() ),
488 this, SLOT( slotLibraryDestroyed() ) );
489
490 return wrap->lib;
491}
492
493QString KLibLoader::lastErrorMessage() const
494{
495 return d->errorMessage;
496}
497
498void KLibLoader::unloadLibrary( const char *libname )
499{
500 KLibWrapPrivate *wrap = m_libs[ libname ];
501 if (!wrap)
502 return;
503 if (--wrap->ref_count)
504 return;
505
506// kdDebug(150) << "closing library " << libname << endl;
507
508 m_libs.remove( libname );
509
510 disconnect( wrap->lib, SIGNAL( destroyed() ),
511 this, SLOT( slotLibraryDestroyed() ) );
512 close_pending( wrap );
513}
514
515KLibFactory* KLibLoader::factory( const char* name )
516{
517 KLibrary* lib = library( name );
518 if ( !lib )
519 return 0;
520
521 return lib->factory();
522}
523
524void KLibLoader::slotLibraryDestroyed()
525{
526 const KLibrary *lib = static_cast<const KLibrary *>( sender() );
527
528 QAsciiDictIterator<KLibWrapPrivate> it( m_libs );
529 for (; it.current(); ++it )
530 if ( it.current()->lib == lib )
531 {
532 KLibWrapPrivate *wrap = it.current();
533 wrap->lib = 0; /* the KLibrary object is already away */
534 m_libs.remove( it.currentKey() );
535 close_pending( wrap );
536 return;
537 }
538}
539
540void KLibLoader::close_pending(KLibWrapPrivate *wrap)
541{
542 if (wrap && !d->pending_close.containsRef( wrap ))
543 d->pending_close.append( wrap );
544
545 /* First delete all KLibrary objects in pending_close, but _don't_ unload
546 the DSO behind it. */
547 QPtrListIterator<KLibWrapPrivate> it(d->pending_close);
548 for (; it.current(); ++it) {
549 wrap = it.current();
550 if (wrap->lib) {
551 disconnect( wrap->lib, SIGNAL( destroyed() ),
552 this, SLOT( slotLibraryDestroyed() ) );
553 delete wrap->lib;
554 wrap->lib = 0;
555 }
556 }
557
558 if (d->unload_mode == KLibLoaderPrivate::DONT_UNLOAD) return;
559
560 bool deleted_one = false;
561 while ((wrap = d->loaded_stack.first())) {
562 /* Let's first see, if we want to try to unload this lib.
563 If the env. var KDE_DOUNLOAD is set, we try to unload every lib.
564 If not, we look at the lib itself, and unload it only, if it exports
565 the symbol __kde_do_unload. */
566 if (d->unload_mode != KLibLoaderPrivate::UNLOAD
567 && wrap->unload_mode != KLibWrapPrivate::UNLOAD)
568 break;
569
570 /* Now ensure, that the libs are only unloaded in the reverse direction
571 they were loaded. */
572 if (!d->pending_close.containsRef( wrap )) {
573 if (!deleted_one)
574 /* Only diagnose, if we really haven't deleted anything. */
575// kdDebug(150) << "try to dlclose " << wrap->name << ": not yet" << endl;
576 break;
577 }
578
579// kdDebug(150) << "try to dlclose " << wrap->name << ": yes, done." << endl;
580
581#ifndef Q_WS_QWS
582 if ( !deleted_one ) {
583 /* Only do the hack once in this loop.
584 WABA: *HACK*
585 We need to make sure to clear the clipboard before unloading a DSO
586 because the DSO could have defined an object derived from QMimeSource
587 and placed that on the clipboard. */
588 /*kapp->clipboard()->clear();*/
589
590 /* Well.. let's do something more subtle... convert the clipboard context
591 to text. That should be safe as it only uses objects defined by Qt. */
592
593 QWidgetList *widgetlist = QApplication::topLevelWidgets();
594 QWidget *co = widgetlist->first();
595 while (co) {
596 if (qstrcmp(co->name(), "internal clipboard owner") == 0) {
597 if (XGetSelectionOwner(co->x11Display(), XA_PRIMARY) == co->winId())
598 kapp->clipboard()->setText(kapp->clipboard()->text());
599
600 break;
601 }
602 co = widgetlist->next();
603 }
604 delete widgetlist;
605 }
606#else
607 // FIXME(E): Implement in Qt Embedded
608#endif
609
610 deleted_one = true;
611//US lt_dlclose(wrap->handle);
612 wrap->handle->unload();
613
614 d->pending_close.removeRef(wrap);
615 /* loaded_stack is AutoDelete, so wrap is freed */
616 d->loaded_stack.remove();
617 }
618}
619
620void KLibLoader::virtual_hook( int, void* )
621{ /*BASE::virtual_hook( id, data );*/ }
622
623void KLibFactory::virtual_hook( int, void* )
624{ /*BASE::virtual_hook( id, data );*/ }
625
626//US #include "klibloader.moc"
diff --git a/microkde/kdecore/klibloader.h b/microkde/kdecore/klibloader.h
new file mode 100644
index 0000000..ed57109
--- a/dev/null
+++ b/microkde/kdecore/klibloader.h
@@ -0,0 +1,405 @@
1/* This file is part of the KDE libraries
2 Copyright (C) 1999 Torben Weis <weis@kde.org>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License version 2 as published by the Free Software Foundation.
7
8 This library is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 Library General Public License for more details.
12
13 You should have received a copy of the GNU Library General Public License
14 along with this library; see the file COPYING.LIB. If not, write to
15 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16 Boston, MA 02111-1307, USA.
17*/
18#ifndef KLIBLOADER_H
19#define KLIBLOADER_H
20
21#include <qobject.h>
22#include <qstring.h>
23#include <qstringlist.h>
24#include <qasciidict.h>
25#include <qptrlist.h>
26#include <kglobal.h>
27
28#include <stdlib.h> // For backwards compatibility
29
30class KInstance;
31class QTimer;
32class KLibrary;
33class KLibFactory;
34class KLibFactoryPrivate;
35class KLibLoaderPrivate;
36class KLibraryPrivate;
37
38class QLibrary;
39
40#define K_EXPORT_COMPONENT_FACTORY( libname, factory ) \
41 extern "C" { void *init_##libname() { return new factory; } }
42
43/**
44 * @short Represents a dynamically loaded library.
45 *
46 * KLibrary allows you to look up symbols of the shared library.
47 * Use @ref KLibLoader to create a new instance of KLibrary.
48 *
49 * @see KLibLoader
50 * @author Torben Weis <weis@kde.org>
51 */
52class KLibrary : public QObject
53{
54 friend class KLibLoader;
55 friend class QAsciiDict<KLibrary>;
56
57 Q_OBJECT
58public:
59 /**
60 * @internal
61 * Don't create KLibrary objects on your own. Instead use @ref KLibLoader.
62 */
63//US KLibrary( const QString& libname, const QString& filename, void * handle );
64 KLibrary( const QString& libname, const QString& filename, QLibrary* handle );
65
66 /**
67 * Returns the name of the library.
68 * @return The name of the library like "libkspread".
69 */
70 QString name() const;
71
72 /**
73 * Returns the file name of the library.
74 * @return The filename of the library, for example "/opt/kde2&/lib/libkspread.la"
75 */
76 QString fileName() const;
77
78 /**
79 * Returns the factory of the library.
80 * @return The factory of the library if there is any, otherwise 0
81 */
82 KLibFactory* factory();
83
84 /**
85 * Looks up a symbol from the library. This is a very low level
86 * function that you usually don't want to use. Usually you should
87 * check using @ref hasSymbol() whether the symbol actually exists,
88 * otherwise a warning will be printed.
89 * @param name the name of the symbol to look up
90 * @return the address of the symbol, or 0 if it does not exist
91 * @see #hasSymbol
92 */
93 void* symbol( const char* name ) const;
94
95 /**
96 * Looks up a symbol from the library. This is a very low level
97 * function that you usually don't want to use.
98 * Unlike @ref symbol(), this method doesn't warn if the symbol doesn't exist,
99 * so if the symbol might or might not exist, better use hasSymbol() before symbol().
100 * @param name the name of the symbol to check
101 * @return true if the symbol exists
102 * @since 3.1
103 */
104 bool hasSymbol( const char* name ) const;
105
106 /**
107 * Unloads the library.
108 * This typically results in the deletion of this object. You should
109 * not reference its pointer after calling this function.
110 */
111 void unload() const;
112
113private slots:
114 void slotObjectCreated( QObject *obj );
115 void slotObjectDestroyed();
116 void slotTimeout();
117
118private:
119 /**
120 * @internal
121 * Don't destruct KLibrary objects yourself. Instead use @ref unload() instead.
122 */
123 ~KLibrary();
124
125 QString m_libname;
126 QString m_filename;
127 KLibFactory* m_factory;
128//US void * m_handle;
129 QLibrary* m_handle;
130 QPtrList<QObject> m_objs;
131 QTimer *m_timer;
132 KLibraryPrivate *d;
133};
134
135class KLibWrapPrivate;
136
137/**
138 * The KLibLoader allows you to load libraries dynamically at runtime.
139 * Dependent libraries are loaded automatically.
140 *
141 * KLibLoader follows the singleton pattern. You can not create multiple
142 * instances. Use @ref self() to get a pointer to the loader.
143 *
144 * @see KLibrary
145 * @author Torben Weis <weis@kde.org>
146 */
147class KLibLoader : public QObject
148{
149 friend class KLibrary;
150
151 Q_OBJECT
152public:
153 /**
154 * You should NEVER destruct an instance of KLibLoader
155 * until you know what you are doing. This will release
156 * the loaded libraries.
157 */
158 ~KLibLoader();
159
160 /**
161 * Loads and initializes a library. Loading a library multiple times is
162 * handled gracefully.
163 *
164 * This is a convenience function that returns the factory immediately
165 * @param libname This is the library name without extension. Usually that is something like
166 * "libkspread". The function will then search for a file named
167 * "libkspread.la" in the KDE library paths.
168 * The *.la files are created by libtool and contain
169 * important information especially about the libraries dependencies
170 * on other shared libs. Loading a "libfoo.so" could not solve the
171 * dependencies problem.
172 *
173 * You can, however, give a library name ending in ".so"
174 * (or whatever is used on your platform), and the library
175 * will be loaded without resolving dependencies. USE WITH CARE :)
176 * @return the @ref KLibFactory, or 0 if the library does not exist or it does
177 * not have a factory
178 * @see #library
179 */
180 KLibFactory* factory( const char* libname );
181
182 /**
183 * Loads and initializes a library. Loading a library multiple times is
184 * handled gracefully.
185 *
186 * @param libname This is the library name without extension. Usually that is something like
187 * "libkspread". The function will then search for a file named
188 * "libkspread.la" in the KDE library paths.
189 * The *.la files are created by libtool and contain
190 * important information especially about the libraries dependencies
191 * on other shared libs. Loading a "libfoo.so" could not solve the
192 * dependencies problem.
193 *
194 * You can, however, give a library name ending in ".so"
195 * (or whatever is used on your platform), and the library
196 * will be loaded without resolving dependencies. USE WITH CARE :)
197 * @return @ref KLibrary is invalid (0) when the library couldn't be dlopened. in such
198 * a case you can retrieve the error message by calling KLibLoader::lastErrorMessage()
199 *
200 * @see #factory
201 */
202 virtual KLibrary* library( const char* libname );
203
204 /**
205 * Loads and initializes a library. Loading a library multiple times is
206 * handled gracefully. The library is loaded such that the symbols are
207 * globally accessible so libraries with dependencies can be loaded
208 * sequentially.
209 *
210 * @param name This is the library name without extension. Usually that is something like
211 * "libkspread". The function will then search for a file named
212 * "libkspread.la" in the KDE library paths.
213 * The *.la files are created by libtool and contain
214 * important information especially about the libraries dependencies
215 * on other shared libs. Loading a "libfoo.so" could not solve the
216 * dependencies problem.
217 *
218 * You can, however, give a library name ending in ".so"
219 * (or whatever is used on your platform), and the library
220 * will be loaded without resolving dependencies. USE WITH CARE :)
221 * @return KLibrariy is invalid (0) when the library couldn't be dlopened. in such
222 * a case you can retrieve the error message by calling KLibLoader::lastErrorMessage()
223 *
224 * @see #factory
225 */
226 KLibrary* globalLibrary( const char *name );
227
228 /*
229 * Returns an error message that can be useful to debug the problem.
230 * Returns QString::null if the last call to @ref #library() was successful.
231 * You can call this function more than once. The error message is only
232 * reset by a new call to library().
233 * @return the last error message, or QString::null if there was no error
234 */
235 QString lastErrorMessage() const;
236
237 /**
238 * Unloads the library with the given name.
239 * @param libname This is the library name without extension. Usually that is something like
240 * "libkspread". The function will then search for a file named
241 * "libkspread.la" in the KDE library paths.
242 * The *.la files are created by libtool and contain
243 * important information especially about the libraries dependencies
244 * on other shared libs. Loading a "libfoo.so" could not solve the
245 * dependencies problem.
246 *
247 * You can, however, give a library name ending in ".so"
248 * (or whatever is used on your platform), and the library
249 * will be loaded without resolving dependencies. USE WITH CARE :)
250 */
251 virtual void unloadLibrary( const char *libname );
252
253 /**
254 * Returns a pointer to the factory. Use this function to get an instance
255 * of KLibLoader.
256 * @return a pointer to the loader. If no loader exists until now
257 * then one is created.
258 */
259 static KLibLoader* self();
260
261 /**
262 * @internal
263 * Internal Method, called by the KApplication destructor.
264 * Do not call it.
265 * This is what makes it possible to rely on ~KLibFactory
266 * being called in all cases, whether the library is unloaded
267 * while the application is running or when exiting.
268 */
269 static void cleanUp();
270
271 /**
272 * Helper method which looks for a library in the standard paths
273 * ("module" and "lib" resources).
274 * Made public for code that doesn't use KLibLoader itself, but still
275 * wants to open modules.
276 * @param name of the library. If it is not a path, the function searches in
277 * the "module" and "lib" resources. If there is no extension,
278 * ".la" will be appended.
279 * @param instance a KInstance used to get the standard paths
280 */
281 static QString findLibrary( const char * name/*US , const KInstance * instance = KGlobal::instance()*/ );
282
283protected:
284 KLibLoader( QObject* parent = 0, const char* name = 0 );
285
286private slots:
287 void slotLibraryDestroyed();
288private:
289 void close_pending( KLibWrapPrivate * );
290 QAsciiDict<KLibWrapPrivate> m_libs;
291
292 static KLibLoader* s_self;
293
294protected:
295 virtual void virtual_hook( int id, void* data );
296private:
297 KLibLoaderPrivate *d;
298};
299
300/**
301 * If you develop a library that is to be loaded dynamically at runtime, then
302 * you should return a pointer to your factory. The K_EXPORT_COMPONENT_FACTORY
303 * macro is provided for this purpose:
304 * <pre>
305 * K_EXPORT_COMPONENT_FACTORY( libkspread, KSpreadFactory )
306 * </pre>
307 *
308 * The first macro argument is the name of your library, the second specifies the name
309 * of your factory.
310 *
311 * In the constructor of your factory you should create an instance of @ref KInstance
312 * like this:
313 * <pre>
314 * s_global = new KInstance( "kspread" );
315 * </pre>
316 * This @ref KInstance is comparable to @ref KGlobal used by normal applications.
317 * It allows you to find resource files (images, XML, sound etc.) belonging
318 * to the library.
319 *
320 * If you want to load a library, use @ref KLibLoader. You can query @ref KLibLoader
321 * directly for a pointer to the libraries factory by using the @ref KLibLoader::factory()
322 * function.
323 *
324 * The KLibFactory is used to create the components, the library has to offer.
325 * The factory of KSpread for example will create instances of KSpreadDoc,
326 * while the Konqueror factory will create KonqView widgets.
327 * All objects created by the factory must be derived from @ref QObject, since @ref QObject
328 * offers type safe casting.
329 *
330 * KLibFactory is an abstract class. Reimplement the @ref
331 * createObject() method to give it functionality.
332 *
333 * @author Torben Weis <weis@kde.org>
334 */
335class KLibFactory : public QObject
336{
337 Q_OBJECT
338public:
339 /**
340 * Create a new factory.
341 * @param parent the parent of the QObject, 0 for no parent
342 * @param name the name of the QObject, 0 for no name
343 */
344 KLibFactory( QObject* parent = 0, const char* name = 0 );
345 virtual ~KLibFactory();
346
347 /**
348 * Creates a new object. The returned object has to be derived from
349 * the requested classname.
350 *
351 * It is valid behavior to create different kinds of objects
352 * depending on the requested @p classname. For example a koffice
353 * library may usually return a pointer to KoDocument. But
354 * if asked for a "QWidget", it could create a wrapper widget,
355 * that encapsulates the Koffice specific features.
356 *
357 * create() automatically emits a signal @ref objectCreated to tell
358 * the library about its newly created object. This is very
359 * important for reference counting, and allows unloading the
360 * library automatically once all its objects have been destroyed.
361 *
362 * @param parent the parent of the QObject, 0 for no parent
363 * @param name the name of the QObject, 0 for no name
364 * @param classname the name of the class
365 * @param args a list of arguments
366 */
367
368 QObject* create( QObject* parent = 0, const char* name = 0, const char* classname = "QObject", const QStringList &args = QStringList() );
369
370signals:
371 /**
372 * Emitted in #create
373 * @param obj the new object
374 */
375 void objectCreated( QObject *obj );
376
377
378protected:
379
380 /**
381 * Creates a new object. The returned object has to be derived from
382 * the requested classname.
383 *
384 * It is valid behavior to create different kinds of objects
385 * depending on the requested @p classname. For example a koffice
386 * library may usually return a pointer to KoDocument. But
387 * if asked for a "QWidget", it could create a wrapper widget,
388 * that encapsulates the Koffice specific features.
389 *
390 * This function is called by #create()
391 * @param parent the parent of the QObject, 0 for no parent
392 * @param name the name of the QObject, 0 for no name
393 * @param classname the name of the class
394 * @param args a list of arguments
395 */
396 virtual QObject* createObject( QObject* parent = 0, const char* name = 0, const char* classname = "QObject", const QStringList &args = QStringList() ) = 0;
397
398
399protected:
400 virtual void virtual_hook( int id, void* data );
401private:
402 KLibFactoryPrivate *d;
403};
404
405#endif
diff --git a/microkde/kdecore/klocale.cpp b/microkde/kdecore/klocale.cpp
new file mode 100644
index 0000000..d77e251
--- a/dev/null
+++ b/microkde/kdecore/klocale.cpp
@@ -0,0 +1,881 @@
1#include <qregexp.h>
2#include <qapplication.h>
3
4#include "kdebug.h"
5#include "kcalendarsystemgregorian.h"
6
7#include "klocale.h"
8
9
10QDict<QString> *mLocaleDict = 0;
11void setLocaleDict( QDict<QString> * dict )
12{
13 mLocaleDict = dict;
14
15}
16QString i18n(const char *text)
17{
18 if ( ! mLocaleDict )
19 return QString( text );
20 else {
21 QString* ret = mLocaleDict->find(QString(text)) ;
22 if ( ret == 0 ) {
23 return QString( text );
24 }
25 else {
26 if ( (*ret).isEmpty() )
27 return QString( text );
28 else
29 return (*ret);
30 }
31 }
32
33}
34
35QString i18n(const char *,const char *text)
36{
37 return i18n( text );
38}
39
40QString i18n(const char *text1, const char *textn, int num)
41{
42 if ( num == 1 ) return i18n( text1 );
43 else {
44 QString text = i18n( textn );
45 int pos = text.find( "%n" );
46 if ( pos >= 0 ) text.replace( pos, 2, QString::number( num ) );
47 return text;
48 }
49}
50
51inline void put_it_in( QChar *buffer, uint& index, const QString &s )
52{
53 for ( uint l = 0; l < s.length(); l++ )
54 buffer[index++] = s.at( l );
55}
56
57inline void put_it_in( QChar *buffer, uint& index, int number )
58{
59 buffer[index++] = number / 10 + '0';
60 buffer[index++] = number % 10 + '0';
61}
62
63static int readInt(const QString &str, uint &pos)
64{
65 if (!str.at(pos).isDigit()) return -1;
66 int result = 0;
67 for (; str.length() > pos && str.at(pos).isDigit(); pos++)
68 {
69 result *= 10;
70 result += str.at(pos).digitValue();
71 }
72
73 return result;
74}
75
76KLocale::KLocale() : mCalendarSystem( 0 )
77{
78
79 m_decimalSymbol = ".";
80 m_positiveSign = "";
81 m_negativeSign = "-";
82 m_thousandsSeparator = ",";
83
84
85
86
87 mWeekStartsMonday = true;
88 mHourF24Format = true;
89 mIntDateFormat = 0;
90 mLanguage = 0;
91 mDateFormat = "%a %Y %b %d";
92 mDateFormatShort = "%Y-%m-%d";
93 mTimeZoneList << i18n ("-11:00 US/Samoa")
94 << i18n ("-10:00 US/Hawaii")
95 << i18n ("-09:00 US/Alaska")
96 << i18n ("-08:00 US/Pacific")
97 << i18n ("-07:00 US/Mountain")
98 << i18n ("-06:00 US/Central")
99 << i18n ("-05:00 US/Eastern")
100 << i18n ("-04:00 Brazil/West")
101 << i18n ("-03:00 Brazil/East")
102 << i18n ("-02:00 Brazil/DeNoronha")
103 << i18n ("-01:00 Atlantic/Azores")
104 << i18n (" 00:00 Europe/London(UTC)")
105 << i18n ("+01:00 Europe/Oslo(CET)")
106 << i18n ("+02:00 Europe/Helsinki")
107 << i18n ("+03:00 Europe/Moscow")
108 << i18n ("+04:00 Indian/Mauritius")
109 << i18n ("+05:00 Indian/Maldives")
110 << i18n ("+06:00 Indian/Chagos")
111 << i18n ("+07:00 Asia/Bangkok")
112 << i18n ("+08:00 Asia/Hongkong")
113 << i18n ("+09:00 Asia/Tokyo")
114 << i18n ("+10:00 Asia/Vladivostok")
115 << i18n ("+11:00 Asia/Magadan")
116 << i18n ("+12:00 Asia/Kamchatka")
117 // << i18n (" xx:xx User defined offset")
118 << i18n (" Local Time");
119 mSouthDaylight = false;
120 mTimeZoneOffset = 0;
121 daylightEnabled = false;
122}
123
124void KLocale::setDateFormat( QString s )
125{
126 mDateFormat = s;
127}
128
129void KLocale::setDateFormatShort( QString s )
130{
131 mDateFormatShort = s;
132}
133
134void KLocale::setHore24Format ( bool b )
135{
136 mHourF24Format = b;
137}
138void KLocale::setWeekStartMonday( bool b )
139{
140 mWeekStartsMonday = b;
141}
142int KLocale::getIntDateFormat( )
143{
144 return mIntDateFormat ;
145
146}
147void KLocale::setIntDateFormat( int i )
148{
149 mIntDateFormat = i;
150}
151void KLocale::setLanguage( int i )
152{
153 mLanguage = i;
154}
155QString KLocale::translate( const char *index ) const
156{
157 return i18n( index );
158}
159
160QString KLocale::translate( const char *, const char *fallback) const
161{
162 return i18n( fallback );
163}
164
165QString KLocale::formatTime(const QTime &pTime, bool includeSecs) const
166{
167 const QString rst = timeFormat();
168
169 // only "pm/am" here can grow, the rest shrinks, but
170 // I'm rather safe than sorry
171 QChar *buffer = new QChar[rst.length() * 3 / 2 + 30];
172
173 uint index = 0;
174 bool escape = false;
175 int number = 0;
176
177 for ( uint format_index = 0; format_index < rst.length(); format_index++ )
178 {
179 if ( !escape )
180 {
181 if ( rst.at( format_index ).unicode() == '%' )
182 escape = true;
183 else
184 buffer[index++] = rst.at( format_index );
185 }
186 else
187 {
188 switch ( rst.at( format_index ).unicode() )
189 {
190 case '%':
191 buffer[index++] = '%';
192 break;
193 case 'H':
194 put_it_in( buffer, index, pTime.hour() );
195 break;
196 case 'I':
197 put_it_in( buffer, index, ( pTime.hour() + 11) % 12 + 1 );
198 break;
199 case 'M':
200 put_it_in( buffer, index, pTime.minute() );
201 break;
202 case 'S':
203 if (includeSecs)
204 put_it_in( buffer, index, pTime.second() );
205 else
206 {
207 // we remove the seperator sign before the seconds and
208 // assume that works everywhere
209 --index;
210 break;
211 }
212 break;
213 case 'k':
214 number = pTime.hour();
215 case 'l':
216 // to share the code
217 if ( rst.at( format_index ).unicode() == 'l' )
218 number = (pTime.hour() + 11) % 12 + 1;
219 if ( number / 10 )
220 buffer[index++] = number / 10 + '0';
221 buffer[index++] = number % 10 + '0';
222 break;
223 case 'p':
224 {
225 QString s;
226 if ( pTime.hour() >= 12 )
227 put_it_in( buffer, index, i18n("pm") );
228 else
229 put_it_in( buffer, index, i18n("am") );
230 break;
231 }
232 default:
233 buffer[index++] = rst.at( format_index );
234 break;
235 }
236 escape = false;
237 }
238 }
239 QString ret( buffer, index );
240 delete [] buffer;
241 return ret;
242}
243
244QString KLocale::formatDate(const QDate &pDate, bool shortFormat) const
245{
246 const QString rst = shortFormat?dateFormatShort():dateFormat();
247
248 // I'm rather safe than sorry
249 QChar *buffer = new QChar[rst.length() * 3 / 2 + 50];
250
251 unsigned int index = 0;
252 bool escape = false;
253 int number = 0;
254
255 for ( uint format_index = 0; format_index < rst.length(); ++format_index )
256 {
257 if ( !escape )
258 {
259 if ( rst.at( format_index ).unicode() == '%' )
260 escape = true;
261 else
262 buffer[index++] = rst.at( format_index );
263 }
264 else
265 {
266 switch ( rst.at( format_index ).unicode() )
267 {
268 case '%':
269 buffer[index++] = '%';
270 break;
271 case 'Y':
272 put_it_in( buffer, index, pDate.year() / 100 );
273 case 'y':
274 put_it_in( buffer, index, pDate.year() % 100 );
275 break;
276 case 'n':
277 number = pDate.month();
278 case 'e':
279 // to share the code
280 if ( rst.at( format_index ).unicode() == 'e' )
281 number = pDate.day();
282 if ( number / 10 )
283 buffer[index++] = number / 10 + '0';
284 buffer[index++] = number % 10 + '0';
285 break;
286 case 'm':
287 put_it_in( buffer, index, pDate.month() );
288 break;
289 case 'b':
290 put_it_in( buffer, index, monthName(pDate.month(), true) );
291 break;
292 case 'B':
293 put_it_in( buffer, index, monthName(pDate.month(), false) );
294 break;
295 case 'd':
296 put_it_in( buffer, index, pDate.day() );
297 break;
298 case 'a':
299 put_it_in( buffer, index, weekDayName(pDate.dayOfWeek(), true) );
300 break;
301 case 'A':
302 put_it_in( buffer, index, weekDayName(pDate.dayOfWeek(), false) );
303 break;
304 default:
305 buffer[index++] = rst.at( format_index );
306 break;
307 }
308 escape = false;
309 }
310 }
311 QString ret( buffer, index );
312 delete [] buffer;
313 return ret;
314}
315
316QString KLocale::formatDateTime(const QDateTime &pDateTime,
317 bool shortFormat,
318 bool includeSeconds) const
319{
320 return QString( "%1 %2")
321 .arg( formatDate( pDateTime.date(), shortFormat ) )
322 .arg( formatTime( pDateTime.time(), includeSeconds ) );
323}
324
325QString KLocale::formatDateTime(const QDateTime &pDateTime) const
326{
327 return formatDateTime(pDateTime, true);
328}
329
330QDate KLocale::readDate(const QString &intstr, bool* ok) const
331{
332 QDate date;
333 date = readDate(intstr, true, ok);
334 if (date.isValid()) return date;
335 return readDate(intstr, false, ok);
336}
337
338QDate KLocale::readDate(const QString &intstr, bool shortFormat, bool* ok) const
339{
340 QString fmt = (shortFormat ? dateFormatShort() : dateFormat()).simplifyWhiteSpace();
341 return readDate( intstr, fmt, ok );
342}
343
344QDate KLocale::readDate(const QString &intstr, const QString &fmt, bool* ok) const
345{
346 //kdDebug(173) << "KLocale::readDate intstr=" << intstr << " fmt=" << fmt << endl;
347 QString str = intstr.simplifyWhiteSpace().lower();
348 int day = -1, month = -1;
349 // allow the year to be omitted if not in the format
350 int year = QDate::currentDate().year();
351 uint strpos = 0;
352 uint fmtpos = 0;
353
354 while (fmt.length() > fmtpos || str.length() > strpos)
355 {
356 if ( !(fmt.length() > fmtpos && str.length() > strpos) )
357 goto error;
358
359 QChar c = fmt.at(fmtpos++);
360
361 if (c != '%') {
362 if (c.isSpace())
363 strpos++;
364 else if (c != str.at(strpos++))
365 goto error;
366 continue;
367 }
368
369 // remove space at the begining
370 if (str.length() > strpos && str.at(strpos).isSpace())
371 strpos++;
372
373 c = fmt.at(fmtpos++);
374 switch (c)
375 {
376 case 'a':
377 case 'A':
378 // this will just be ignored
379 { // Cristian Tache: porting to Win: Block added because of "j" redefinition
380 for (int j = 1; j < 8; j++) {
381 QString s = weekDayName(j, c == 'a').lower();
382 int len = s.length();
383 if (str.mid(strpos, len) == s)
384 strpos += len;
385 }
386 break;
387 }
388 case 'b':
389 case 'B':
390 { // Cristian Tache: porting to Win: Block added because of "j" redefinition
391 for (int j = 1; j < 13; j++) {
392 QString s = monthName(j, c == 'b').lower();
393 int len = s.length();
394 if (str.mid(strpos, len) == s) {
395 month = j;
396 strpos += len;
397 }
398 }
399 break;
400 }
401 case 'd':
402 case 'e':
403 day = readInt(str, strpos);
404 if (day < 1 || day > 31)
405 goto error;
406
407 break;
408
409 case 'n':
410 case 'm':
411 month = readInt(str, strpos);
412 if (month < 1 || month > 12)
413 goto error;
414
415 break;
416
417 case 'Y':
418 case 'y':
419 year = readInt(str, strpos);
420 if (year < 0)
421 goto error;
422 // Qt treats a year in the range 0-100 as 1900-1999.
423 // It is nicer for the user if we treat 0-68 as 2000-2068
424 if (year < 69)
425 year += 2000;
426 else if (c == 'y')
427 year += 1900;
428
429 break;
430 }
431 }
432 //kdDebug(173) << "KLocale::readDate day=" << day << " month=" << month << " year=" << year << endl;
433 if ( year != -1 && month != -1 && day != -1 )
434 {
435 if (ok) *ok = true;
436 return QDate(year, month, day);
437 }
438 error:
439 if (ok) *ok = false;
440 return QDate(); // invalid date
441}
442
443QTime KLocale::readTime(const QString &intstr, bool *ok) const
444{
445 QTime _time;
446 _time = readTime(intstr, true, ok);
447 if (_time.isValid()) return _time;
448 return readTime(intstr, false, ok);
449}
450
451QTime KLocale::readTime(const QString &intstr, bool seconds, bool *ok) const
452{
453 QString str = intstr.simplifyWhiteSpace().lower();
454 QString Format = timeFormat().simplifyWhiteSpace();
455 if (!seconds)
456 Format.replace(QRegExp(QString::fromLatin1(".%S")), QString::null);
457
458 int hour = -1, minute = -1, second = seconds ? -1 : 0; // don't require seconds
459 bool g_12h = false;
460 bool pm = false;
461 uint strpos = 0;
462 uint Formatpos = 0;
463
464 while (Format.length() > Formatpos || str.length() > strpos)
465 {
466 if ( !(Format.length() > Formatpos && str.length() > strpos) ) goto error;
467
468 QChar c = Format.at(Formatpos++);
469
470 if (c != '%')
471 {
472 if (c.isSpace())
473 strpos++;
474 else if (c != str.at(strpos++))
475 goto error;
476 continue;
477 }
478
479 // remove space at the begining
480 if (str.length() > strpos && str.at(strpos).isSpace())
481 strpos++;
482
483 c = Format.at(Formatpos++);
484 switch (c)
485 {
486 case 'p':
487 {
488 QString s;
489 s = i18n("pm").lower();
490 int len = s.length();
491 if (str.mid(strpos, len) == s)
492 {
493 pm = true;
494 strpos += len;
495 }
496 else
497 {
498 s = i18n("am").lower();
499 len = s.length();
500 if (str.mid(strpos, len) == s) {
501 pm = false;
502 strpos += len;
503 }
504 else
505 goto error;
506 }
507 }
508 break;
509
510 case 'k':
511 case 'H':
512 g_12h = false;
513 hour = readInt(str, strpos);
514 if (hour < 0 || hour > 23)
515 goto error;
516
517 break;
518
519 case 'l':
520 case 'I':
521 g_12h = true;
522 hour = readInt(str, strpos);
523 if (hour < 1 || hour > 12)
524 goto error;
525
526 break;
527
528 case 'M':
529 minute = readInt(str, strpos);
530 if (minute < 0 || minute > 59)
531 goto error;
532
533 break;
534
535 case 'S':
536 second = readInt(str, strpos);
537 if (second < 0 || second > 59)
538 goto error;
539
540 break;
541 }
542 }
543 if (g_12h)
544 {
545 hour %= 12;
546 if (pm) hour += 12;
547 }
548
549 if (ok) *ok = true;
550 return QTime(hour, minute, second);
551
552 error:
553 if (ok) *ok = false;
554 return QTime(-1, -1, -1); // return invalid date if it didn't work
555 // This will be removed in the near future, since it gives a warning on stderr.
556 // The presence of the bool* (since KDE-3.0) removes the need for an invalid QTime.
557}
558
559bool KLocale::use12Clock() const
560{
561 return !mHourF24Format ;;
562}
563
564bool KLocale::weekStartsMonday() const
565{
566 return mWeekStartsMonday;
567}
568
569int KLocale::weekStartDay() const
570{
571 if ( mWeekStartsMonday )
572 return 1;
573 return 7;
574}
575
576QString KLocale::weekDayName(int i,bool shortName) const
577{
578 if ( shortName )
579 switch ( i )
580 {
581 case 1: return i18n("Monday", "Mon");
582 case 2: return i18n("Tuesday", "Tue");
583 case 3: return i18n("Wednesday", "Wed");
584 case 4: return i18n("Thursday", "Thu");
585 case 5: return i18n("Friday", "Fri");
586 case 6: return i18n("Saturday", "Sat");
587 case 7: return i18n("Sunday", "Sun");
588 }
589 else
590 switch ( i )
591 {
592 case 1: return i18n("Monday");
593 case 2: return i18n("Tuesday");
594 case 3: return i18n("Wednesday");
595 case 4: return i18n("Thursday");
596 case 5: return i18n("Friday");
597 case 6: return i18n("Saturday");
598 case 7: return i18n("Sunday");
599 }
600
601 return QString::null;
602}
603
604QString KLocale::monthName(int i,bool shortName) const
605{
606 if ( shortName )
607 switch ( i )
608 {
609 case 1: return i18n("January", "Jan");
610 case 2: return i18n("February", "Feb");
611 case 3: return i18n("March", "Mar");
612 case 4: return i18n("April", "Apr");
613 case 5: return i18n("May short", "May");
614 case 6: return i18n("June", "Jun");
615 case 7: return i18n("July", "Jul");
616 case 8: return i18n("August", "Aug");
617 case 9: return i18n("September", "Sep");
618 case 10: return i18n("October", "Oct");
619 case 11: return i18n("November", "Nov");
620 case 12: return i18n("December", "Dec");
621 }
622 else
623 switch (i)
624 {
625 case 1: return i18n("January");
626 case 2: return i18n("February");
627 case 3: return i18n("March");
628 case 4: return i18n("April");
629 case 5: return i18n("May long", "May");
630 case 6: return i18n("June");
631 case 7: return i18n("July");
632 case 8: return i18n("August");
633 case 9: return i18n("September");
634 case 10: return i18n("October");
635 case 11: return i18n("November");
636 case 12: return i18n("December");
637 }
638
639 return QString::null;
640}
641
642QString KLocale::country() const
643{
644 return QString::null;
645}
646
647QString KLocale::dateFormat() const
648{
649 if ( QApplication::desktop()->width() < 480 ) {
650 if ( mIntDateFormat == 0 )
651 return "%a %d %b %Y";
652 else if ( mIntDateFormat == 1 )
653 return "%a %b %d %Y";
654 else if ( mIntDateFormat == 2 )
655 return "%a %Y %b %d";
656 } else {
657
658 if ( mIntDateFormat == 0 )
659 return "%A %d %B %Y";
660 else if ( mIntDateFormat == 1 )
661 return "%A %B %d %Y";
662 else if ( mIntDateFormat == 2 )
663 return "%A %Y %B %d";
664 }
665 return mDateFormat ;
666}
667
668QString KLocale::dateFormatShort() const
669{
670
671 if ( mIntDateFormat == 0 )
672 return "%d.%m.%Y";
673 else if ( mIntDateFormat == 1 )
674 return "%m.%d.%Y";
675 else if ( mIntDateFormat == 2 )
676 return "%Y-%m-%d";
677 return mDateFormatShort ;
678
679}
680
681
682QString KLocale::timeFormat() const
683{
684 if ( mHourF24Format)
685 return "%H:%M:%S";
686 return "%I:%M:%S%p";
687}
688
689void KLocale::insertCatalogue ( const QString & )
690{
691}
692
693KCalendarSystem *KLocale::calendar()
694{
695 if ( !mCalendarSystem ) {
696 mCalendarSystem = new KCalendarSystemGregorian;
697 }
698
699 return mCalendarSystem;
700}
701
702int KLocale::timezoneOffset( QString timeZone )
703{
704 int ret = 1001;
705 int index = mTimeZoneList.findIndex( timeZone );
706 if ( index < 24 )
707 ret = ( index-11 ) * 60 ;
708 return ret;
709}
710
711QStringList KLocale::timeZoneList() const
712{
713 return mTimeZoneList;
714}
715void KLocale::setTimezone( const QString &timeZone )
716{
717 mTimeZoneOffset = timezoneOffset( timeZone );
718}
719
720void KLocale::setDaylightSaving( bool b, int start , int end )
721{
722 daylightEnabled = b;
723 daylightStart = start;
724 daylightEnd = end;
725 mSouthDaylight = (end < start);
726 // qDebug("klocale daylight %d %d %d ", b, start , end );
727}
728
729int KLocale::localTimeOffset( const QDateTime &dt )
730{
731 bool addDaylight = false;
732 if ( daylightEnabled ) {
733 int d_end, d_start;
734 int dayofyear = dt.date().dayOfYear();
735 int year = dt.date().year();
736 int add = 0;
737 if ( QDate::leapYear(year) )
738 add = 1;
739 QDate date ( year,1,1 );
740 if ( daylightEnd > 59 )
741 d_end = daylightEnd +add;
742 else
743 d_end = daylightEnd;
744 if ( daylightStart > 59 )
745 d_start = daylightStart +add;
746 else
747 d_start = daylightStart;
748 QDate s_date = date.addDays( d_start -1 );
749 QDate e_date = date.addDays( d_end -1 );
750 int dof = s_date.dayOfWeek();
751 if ( dof < 7 )
752 s_date = s_date.addDays( -dof );
753 dof = e_date.dayOfWeek();
754 if ( dof < 7 )
755 e_date = e_date.addDays( -dof );
756 QTime startTime ( 3,0,0 );
757 QDateTime startDt( s_date, startTime );
758 QDateTime endDt( e_date, startTime );
759 //qDebug("dayligt saving start %s end %s ",startDt.toString().latin1(),endDt.toString().latin1( ));
760 if ( mSouthDaylight ) {
761 if ( ! ( endDt < dt && dt < startDt) )
762 addDaylight = true;
763 } else {
764 if ( startDt < dt && dt < endDt )
765 addDaylight = true;
766
767
768 }
769 }
770 int addMin = 0;
771 if ( addDaylight )
772 addMin = 60;
773 return mTimeZoneOffset + addMin;
774}
775// ******************************************************************
776// added LR
777QString KLocale::formatNumber(double num, int precision) const
778{
779 bool neg = num < 0;
780 if (precision == -1) precision = 2;
781 QString res = QString::number(neg?-num:num, 'f', precision);
782 int pos = res.find('.');
783 if (pos == -1) pos = res.length();
784 else res.replace(pos, 1, decimalSymbol());
785
786 while (0 < (pos -= 3))
787 res.insert(pos, thousandsSeparator()); // thousand sep
788
789 // How can we know where we should put the sign?
790 res.prepend(neg?negativeSign():positiveSign());
791
792 return res;
793}
794QString KLocale::formatNumber(const QString &numStr) const
795{
796 return formatNumber(numStr.toDouble());
797}
798double KLocale::readNumber(const QString &_str, bool * ok) const
799{
800 QString str = _str.stripWhiteSpace();
801 bool neg = str.find(negativeSign()) == 0;
802 if (neg)
803 str.remove( 0, negativeSign().length() );
804
805 /* will hold the scientific notation portion of the number.
806 Example, with 2.34E+23, exponentialPart == "E+23"
807 */
808 QString exponentialPart;
809 int EPos;
810
811 EPos = str.find('E', 0, false);
812
813 if (EPos != -1)
814 {
815 exponentialPart = str.mid(EPos);
816 str = str.left(EPos);
817 }
818
819 int pos = str.find(decimalSymbol());
820 QString major;
821 QString minor;
822 if ( pos == -1 )
823 major = str;
824 else
825 {
826 major = str.left(pos);
827 minor = str.mid(pos + decimalSymbol().length());
828 }
829
830 // Remove thousand separators
831 int thlen = thousandsSeparator().length();
832 int lastpos = 0;
833 while ( ( pos = major.find( thousandsSeparator() ) ) > 0 )
834 {
835 // e.g. 12,,345,,678,,922 Acceptable positions (from the end) are 5, 10, 15... i.e. (3+thlen)*N
836 int fromEnd = major.length() - pos;
837 if ( fromEnd % (3+thlen) != 0 // Needs to be a multiple, otherwise it's an error
838 || pos - lastpos > 3 // More than 3 digits between two separators -> error
839 || pos == 0 // Can't start with a separator
840 || (lastpos>0 && pos-lastpos!=3)) // Must have exactly 3 digits between two separators
841 {
842 if (ok) *ok = false;
843 return 0.0;
844 }
845
846 lastpos = pos;
847 major.remove( pos, thlen );
848 }
849 if (lastpos>0 && major.length()-lastpos!=3) // Must have exactly 3 digits after the last separator
850 {
851 if (ok) *ok = false;
852 return 0.0;
853 }
854
855 QString tot;
856 if (neg) tot = '-';
857
858 tot += major + '.' + minor + exponentialPart;
859
860 return tot.toDouble(ok);
861}
862QString KLocale::decimalSymbol() const
863{
864
865 return m_decimalSymbol;
866}
867
868QString KLocale::thousandsSeparator() const
869{
870
871 return m_thousandsSeparator;
872}
873QString KLocale::positiveSign() const
874{
875 return m_positiveSign;
876}
877
878QString KLocale::negativeSign() const
879{
880 return m_negativeSign;
881}
diff --git a/microkde/kdecore/klocale.h b/microkde/kdecore/klocale.h
new file mode 100644
index 0000000..7470cd2
--- a/dev/null
+++ b/microkde/kdecore/klocale.h
@@ -0,0 +1,110 @@
1#ifndef MINIKDE_KLOCALE_H
2#define MINIKDE_KLOCALE_H
3
4#include <qstring.h>
5#include <qstringlist.h>
6#include <qdatetime.h>
7#include <qdict.h>
8
9#ifndef I18N_NOOP
10#define I18N_NOOP(x) (x)
11#endif
12
13class KCalendarSystem;
14void setLocaleDict( QDict<QString> * dict );
15QString i18n(const char *text);
16QString i18n(const char *hint, const char *text);
17QString i18n(const char *text1, const char *textn, int num);
18
19// Qt3's uic generates i18n( "msg", "comment" ) calls which conflict
20// with our i18n method. we use uic -tr tr2i18n to redirect
21// to the right i18n() function
22inline QString tr2i18n(const char* message, const char* =0) {
23 return i18n( message);
24}
25
26class KLocale
27{
28 public:
29 KLocale();
30
31 QString formatNumber(double num, int precision = -1) const;
32 QString formatNumber(const QString &numStr) const;
33 double readNumber(const QString &numStr, bool * ok = 0) const;
34
35 QString decimalSymbol() const;
36 QString thousandsSeparator() const;
37 QString positiveSign() const;
38 QString negativeSign() const;
39
40
41 QString translate( const char *index ) const;
42 QString translate( const char *index, const char *fallback) const;
43
44 QString formatDate(const QDate &pDate, bool shortFormat = false) const;
45 QString formatTime(const QTime &pTime, bool includeSecs = false) const;
46 QString formatDateTime(const QDateTime &pDateTime) const;
47 QString formatDateTime(const QDateTime &pDateTime,
48 bool shortFormat,
49 bool includeSecs = false) const;
50
51 QDate readDate(const QString &str, bool* ok = 0) const;
52 QDate readDate( const QString &intstr, const QString &fmt, bool* ok = 0) const;
53 QTime readTime(const QString &str, bool* ok = 0) const;
54
55 bool use12Clock() const;
56 bool weekStartsMonday() const;
57 int weekStartDay() const;
58
59 QString weekDayName(int,bool=false) const;
60 QString monthName(int,bool=false) const;
61
62 QString country() const;
63
64 QString dateFormat() const;
65 QString dateFormatShort() const;
66 QString timeFormat() const;
67
68 void insertCatalogue ( const QString & );
69
70 KCalendarSystem *calendar();
71 void setHore24Format ( bool );
72 void setWeekStartMonday( bool );
73 void setIntDateFormat( int );
74 int getIntDateFormat( );
75 void setLanguage( int );
76 void setDateFormat( QString );
77 void setDateFormatShort( QString );
78
79 QString m_decimalSymbol;
80 QString m_thousandsSeparator;
81 QString m_currencySymbol;
82 QString m_monetaryDecimalSymbol;
83 QString m_monetaryThousandsSeparator;
84 QString m_positiveSign;
85 QString m_negativeSign;
86
87 int timezoneOffset( QString );
88 QStringList timeZoneList() const;
89 void setDaylightSaving( bool, int , int );
90 int localTimeOffset(const QDateTime &);
91 void setTimezone( const QString &timeZone );
92 private:
93 QTime readTime(const QString &str, bool seconds, bool *ok) const;
94 QDate readDate(const QString &str, bool shortFormat, bool *ok) const;
95 KCalendarSystem *mCalendarSystem;
96 bool mWeekStartsMonday;
97 bool mHourF24Format;
98 int mIntDateFormat;
99 int mLanguage;
100 QString mDateFormat;
101 QString mDateFormatShort;
102 QStringList mTimeZoneList;
103 bool daylightEnabled;
104 int mDaylightTZoffset;
105 int mNondaylightTZoffset;
106 bool mSouthDaylight;
107 int daylightStart, daylightEnd, mTimeZoneOffset;
108};
109
110#endif
diff --git a/microkde/kdecore/klocale_new.cpp b/microkde/kdecore/klocale_new.cpp
new file mode 100644
index 0000000..223b6c4
--- a/dev/null
+++ b/microkde/kdecore/klocale_new.cpp
@@ -0,0 +1,2441 @@
1// -*- c-basic-offset: 2 -*-
2/* This file is part of the KDE libraries
3 Copyright (c) 1997,2001 Stephan Kulow <coolo@kde.org>
4 Copyright (c) 1999 Preston Brown <pbrown@kde.org>
5 Copyright (c) 1999-2002 Hans Petter Bieker <bieker@kde.org>
6 Copyright (c) 2002 Lukas Tinkl <lukas@kde.org>
7
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Library General Public
10 License as published by the Free Software Foundation; either
11 version 2 of the License, or (at your option) any later version.
12
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Library General Public License for more details.
17
18 You should have received a copy of the GNU Library General Public License
19 along with this library; see the file COPYING.LIB. If not, write to
20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA.
22*/
23
24//US#include <config.h>
25
26#include <stdlib.h> // getenv
27#include <assert.h>
28
29#include <qtextcodec.h>
30#include <qfile.h>
31#include <qdict.h>
32#include <qprinter.h>
33#include <qdatetime.h>
34#include <qfileinfo.h>
35#include <qregexp.h>
36
37#include "kcatalogue.h"
38#include "kglobal.h"
39#include "kstandarddirs.h"
40#include "ksimpleconfig.h"
41//US #include "kinstance.h"
42#include "kconfig.h"
43#include "kconfigbase.h"
44#include "kdebug.h"
45#include "kcalendarsystem.h"
46
47//US we use no factory. Simply use the gregorian calendar
48//US #include "kcalendarsystemfactory.h"
49#include "kcalendarsystemgregorian.h"
50
51#include "klocale.h"
52
53static const char * const SYSTEM_MESSAGES = "kdelibs";
54
55static const char *maincatalogue = 0;
56
57QDict<char> *mLocaleDict = 0;
58
59void setLocaleDict( QDict<char> * dict )
60{
61 mLocaleDict = dict;
62
63}
64
65class KLocalePrivate
66{
67public:
68 int weekStartDay;
69 int plural_form;
70 bool nounDeclension;
71 bool dateMonthNamePossessive;
72 QStringList languageList;
73 QValueList<KCatalogue> catalogues;
74 QString encoding;
75 QTextCodec * codecForEncoding;
76 KConfig * config;
77 bool formatInited;
78 int /*QPrinter::PageSize*/ pageSize;
79 KLocale::MeasureSystem measureSystem;
80 QStringList langTwoAlpha;
81 KConfig *languages;
82
83 QString calendarType;
84 KCalendarSystem * calendar;
85 QString first_language;
86 bool utf8FileEncoding;
87};
88
89static KLocale *this_klocale = 0;
90
91KLocale::KLocale( const QString & catalogue, KConfig * config )
92{
93 d = new KLocalePrivate;
94 d->config = config;
95 d->languages = 0;
96 d->calendar = 0;
97
98 initCatalogue(catalogue);
99 initEncoding(0);
100 initFileNameEncoding(0);
101
102 KConfig *cfg = d->config;
103 this_klocale = this;
104//US if (!cfg) cfg = KGlobal::instance()->config();
105 if (!cfg) cfg = KGlobal::config();
106 this_klocale = 0;
107//US Q_ASSERT( cfg );
108 ASSERT( cfg );
109
110 if (m_language.isEmpty())
111 initLanguage(cfg, config == 0);
112
113
114/*US
115//US mDateFormat = "%a %Y %b %d";
116//US mDateFormatShort = "%Y-%m-%d";
117 mTimeZoneList << i18n ("-11:00 US/Samoa")
118 << i18n ("-10:00 US/Hawaii")
119 << i18n ("-09:00 US/Alaska")
120 << i18n ("-08:00 US/Pacific")
121 << i18n ("-07:00 US/Mountain")
122 << i18n ("-06:00 US/Central")
123 << i18n ("-05:00 US/Eastern")
124 << i18n ("-04:00 Brazil/West")
125 << i18n ("-03:00 Brazil/East")
126 << i18n ("-02:00 Brazil/DeNoronha")
127 << i18n ("-01:00 Atlantic/Azores")
128 << i18n (" 00:00 Europe/London(UTC)")
129 << i18n ("+01:00 Europe/Oslo(CET)")
130 << i18n ("+02:00 Europe/Helsinki")
131 << i18n ("+03:00 Europe/Moscow")
132 << i18n ("+04:00 Indian/Mauritius")
133 << i18n ("+05:00 Indian/Maldives")
134 << i18n ("+06:00 Indian/Chagos")
135 << i18n ("+07:00 Asia/Bangkok")
136 << i18n ("+08:00 Asia/Hongkong")
137 << i18n ("+09:00 Asia/Tokyo")
138 << i18n ("+10:00 Asia/Vladivostok")
139 << i18n ("+11:00 Asia/Magadan")
140 << i18n ("+12:00 Asia/Kamchatka")
141 // << i18n (" xx:xx User defined offset")
142 << i18n (" Local Time");
143*/
144 mTimeZoneList << "-11:00 US/Samoa"
145 << "-10:00 US/Hawaii"
146 << "-09:00 US/Alaska"
147 << "-08:00 US/Pacific"
148 << "-07:00 US/Mountain"
149 << "-06:00 US/Central"
150 << "-05:00 US/Eastern"
151 << "-04:00 Brazil/West"
152 << "-03:00 Brazil/East"
153 << "-02:00 Brazil/DeNoronha"
154 << "-01:00 Atlantic/Azores"
155 << " 00:00 Europe/London(UTC)"
156 << "+01:00 Europe/Oslo(CET)"
157 << "+02:00 Europe/Helsinki"
158 << "+03:00 Europe/Moscow"
159 << "+04:00 Indian/Mauritius"
160 << "+05:00 Indian/Maldives"
161 << "+06:00 Indian/Chagos"
162 << "+07:00 Asia/Bangkok"
163 << "+08:00 Asia/Hongkong"
164 << "+09:00 Asia/Tokyo"
165 << "+10:00 Asia/Vladivostok"
166 << "+11:00 Asia/Magadan"
167 << "+12:00 Asia/Kamchatka"
168 // << " xx:xx User defined offset"
169 << " Local Time";
170
171 mSouthDaylight = false;
172 mTimeZoneOffset = 0;
173 daylightEnabled = false;
174
175 mWeekStartsMonday = true;
176 mHourF24Format = true;
177 mIntDateFormat = 0;
178 mLanguage = 0;
179
180}
181
182
183QString KLocale::_initLanguage(KConfigBase *config)
184{
185 if (this_klocale)
186 {
187 // ### HPB Why this cast??
188 this_klocale->initLanguage((KConfig *) config, true);
189 return this_klocale->language();
190 }
191 return QString::null;
192}
193
194void KLocale::initCatalogue(const QString & catalogue)
195{
196 // Use the first non-null string.
197 QString mainCatalogue = catalogue;
198 if (maincatalogue)
199 mainCatalogue = QString::fromLatin1(maincatalogue);
200
201 if (mainCatalogue.isEmpty()) {
202 kdDebug(173) << "KLocale instance created called without valid "
203 << "catalogue! Give an argument or call setMainCatalogue "
204 << "before init" << endl;
205 }
206 else
207 d->catalogues.append( KCatalogue(mainCatalogue ) );
208
209 // always include kdelibs.mo
210 d->catalogues.append( KCatalogue( SYSTEM_MESSAGES ) );
211}
212
213void KLocale::initLanguage(KConfig * config, bool useEnv)
214{
215 KConfigGroupSaver saver(config, "Locale");
216
217 m_country = config->readEntry( "Country" );
218 if ( m_country.isEmpty() )
219 m_country = defaultCountry();
220
221 // Reset the list and add the new languages
222 QStringList languageList;
223 if ( useEnv )
224 languageList += QStringList::split
225 (':', QFile::decodeName( ::getenv("KDE_LANG") ));
226
227//US languageList += config->readListEntry("Language", ':');
228 languageList += config->readListEntry("Language");
229
230 // same order as setlocale use
231 if ( useEnv )
232 {
233 // HPB: Only run splitLocale on the environment variables..
234 QStringList langs;
235
236 langs << QFile::decodeName( ::getenv("LC_ALL") );
237 langs << QFile::decodeName( ::getenv("LC_MESSAGES") );
238 langs << QFile::decodeName( ::getenv("LANG") );
239 langs << QFile::decodeName( ::getenv("LC_CTYPE") );
240
241 for ( QStringList::Iterator it = langs.begin();
242 it != langs.end();
243 ++it )
244 {
245 QString ln, ct, chrset;
246 splitLocale(*it, ln, ct, chrset);
247
248 if (!ct.isEmpty()) {
249 langs.insert(it, ln + '_' + ct);
250 if (!chrset.isEmpty())
251 langs.insert(it, ln + '_' + ct + '.' + chrset);
252 }
253
254 langs.insert(it, ln);
255 }
256
257 languageList += langs;
258 }
259
260 // now we have a language list -- let's use the first OK language
261 setLanguage( languageList );
262}
263
264void KLocale::doBindInit()
265{
266 return; // LR
267 for ( QValueList<KCatalogue>::Iterator it = d->catalogues.begin();
268 it != d->catalogues.end();
269 ++it )
270 initCatalogue( *it );
271
272 if ( useDefaultLanguage() )
273 d->plural_form = -1;
274 else
275 {
276 QString pf = translate_priv
277 ( I18N_NOOP("_: Dear translator, please do not translate this string "
278 "in any form, but pick the _right_ value out of "
279 "NoPlural/TwoForms/French... If not sure what to do mail "
280 "thd@kde.org and coolo@kde.org, they will tell you. "
281 "Better leave that out if unsure, the programs will "
282 "crash!!\nDefinition of PluralForm - to be set by the "
283 "translator of kdelibs.po"), 0);
284 if ( pf.isEmpty() ) {
285 kdWarning(173) << "found no definition of PluralForm for " << m_language << endl;
286 d->plural_form = -1;
287 } else if ( pf == "NoPlural" )
288 d->plural_form = 0;
289 else if ( pf == "TwoForms" )
290 d->plural_form = 1;
291 else if ( pf == "French" )
292 d->plural_form = 2;
293 else if ( pf == "OneTwoRest" || pf == "Gaeilge" ) // Gaelige is the old name
294 d->plural_form = 3;
295 else if ( pf == "Russian" )
296 d->plural_form = 4;
297 else if ( pf == "Polish" )
298 d->plural_form = 5;
299 else if ( pf == "Slovenian" )
300 d->plural_form = 6;
301 else if ( pf == "Lithuanian" )
302 d->plural_form = 7;
303 else if ( pf == "Czech" )
304 d->plural_form = 8;
305 else if ( pf == "Slovak" )
306 d->plural_form = 9;
307 else if ( pf == "Maltese" )
308 d->plural_form = 10;
309 else if ( pf == "Arabic" )
310 d->plural_form = 11;
311 else if ( pf == "Balcan" )
312 d->plural_form = 12;
313 else {
314 kdWarning(173) << "Definition of PluralForm is none of "
315 << "NoPlural/"
316 << "TwoForms/"
317 << "French/"
318 << "OneTwoRest/"
319 << "Russian/"
320 << "Polish/"
321 << "Slovenian/"
322 << "Lithuanian/"
323 << "Czech/"
324 << "Slovak/"
325 << "Arabic/"
326 << "Balcan/"
327 << "Maltese: " << pf << endl;
328 exit(1);
329 }
330 }
331
332 d->formatInited = false;
333}
334
335void KLocale::doFormatInit() const
336{
337 if ( d->formatInited ) return;
338
339 KLocale * that = const_cast<KLocale *>(this);
340 that->initFormat();
341
342 d->formatInited = true;
343}
344
345void KLocale::initFormat()
346{
347 KConfig *config = d->config;
348//US if (!config) config = KGlobal::instance()->config();
349 if (!config) config = KGlobal::config();
350 ASSERT( config );
351
352 kdDebug(173) << "KLocale::initFormat" << endl;
353
354 // make sure the config files are read using the correct locale
355 // ### Why not add a KConfigBase::setLocale( const KLocale * )?
356 // ### Then we could remove this hack
357//US
358//US KLocale *lsave = KGlobal::_locale;
359//US KGlobal::_locale = this;
360 KLocale *lsave = KGlobal::locale();
361 KGlobal::setLocale(this);
362
363 KConfigGroupSaver saver(config, "Locale");
364
365
366
367//US in kabc/adress.cpp we have a similar setup. Check there in case of problems
368 KSimpleConfig entry(locateLocal("locale",
369 QString::fromLatin1("l10n/%1/entry.desktop")
370 .arg(m_country)) );
371
372 entry.setGroup("KCM Locale");
373
374 // Numeric
375#define readConfigEntry(key, default, save) \
376 save = entry.readEntry(key, QString::fromLatin1(default)); \
377 save = config->readEntry(key, save);
378
379#define readConfigNumEntry(key, default, save, type) \
380 save = (type)entry.readNumEntry(key, default); \
381 save = (type)config->readNumEntry(key, save);
382
383#define readConfigBoolEntry(key, default, save) \
384 save = entry.readBoolEntry(key, default); \
385 save = config->readBoolEntry(key, save);
386
387 readConfigEntry("DecimalSymbol", ".", m_decimalSymbol);
388 readConfigEntry("ThousandsSeparator", ",", m_thousandsSeparator);
389 m_thousandsSeparator.replace( QString::fromLatin1("$0"), QString::null );
390 //kdDebug(173) << "m_thousandsSeparator=" << m_thousandsSeparator << endl;
391
392 readConfigEntry("PositiveSign", "", m_positiveSign);
393 readConfigEntry("NegativeSign", "-", m_negativeSign);
394
395 // Monetary
396 readConfigEntry("CurrencySymbol", "$", m_currencySymbol);
397 readConfigEntry("MonetaryDecimalSymbol", ".", m_monetaryDecimalSymbol);
398 readConfigEntry("MonetaryThousandsSeparator", ",",
399 m_monetaryThousandsSeparator);
400 m_monetaryThousandsSeparator.replace(QString::fromLatin1("$0"), QString::null);
401
402 readConfigNumEntry("FracDigits", 2, m_fracDigits, int);
403 readConfigBoolEntry("PositivePrefixCurrencySymbol", true,
404 m_positivePrefixCurrencySymbol);
405 readConfigBoolEntry("NegativePrefixCurrencySymbol", true,
406 m_negativePrefixCurrencySymbol);
407 readConfigNumEntry("PositiveMonetarySignPosition", (int)BeforeQuantityMoney,
408 m_positiveMonetarySignPosition, SignPosition);
409 readConfigNumEntry("NegativeMonetarySignPosition", (int)ParensAround,
410 m_negativeMonetarySignPosition, SignPosition);
411
412 //Grammatical
413 readConfigBoolEntry("NounDeclension", false, d->nounDeclension);
414
415 // Date and time
416 readConfigEntry("TimeFormat", "%H:%M:%S", m_timeFormat);
417 readConfigEntry("DateFormat", "%A %d %B %Y", m_dateFormat);
418 readConfigEntry("DateFormatShort", "%Y-%m-%d", m_dateFormatShort);
419 readConfigBoolEntry("DateMonthNamePossessive", false,
420 d->dateMonthNamePossessive);
421 readConfigNumEntry("WeekStartDay", 1, d->weekStartDay, int);
422
423 // other
424//US readConfigNumEntry("PageSize", (int)QPrinter::A4, d->pageSize, int);
425 readConfigNumEntry("MeasureSystem", (int)Metric, d->measureSystem,
426 MeasureSystem);
427 readConfigEntry("CalendarSystem", "gregorian", d->calendarType);
428 delete d->calendar;
429 d->calendar = 0; // ### HPB Is this the correct place?
430
431 // end of hack
432//US KGlobal::_locale = lsave;
433 KGlobal::setLocale(lsave);
434}
435
436bool KLocale::setCountry(const QString & country)
437{
438 // Check if the file exists too??
439 if ( country.isEmpty() )
440 return false;
441
442 m_country = country;
443
444 d->formatInited = false;
445
446 return true;
447}
448
449QString KLocale::catalogueFileName(const QString & language,
450 const KCatalogue & catalogue)
451{
452 QString path = QString::fromLatin1("%1/LC_MESSAGES/%2.mo")
453 .arg( language )
454 .arg( catalogue.name() );
455
456 return locate( "locale", path );
457}
458
459bool KLocale::isLanguageInstalled(const QString & language) const
460{
461 // Do not allow empty languages
462 if ( language.isEmpty() ) return false;
463
464 bool bRes = true;
465 if ( language != defaultLanguage() )
466 for ( QValueList<KCatalogue>::ConstIterator it = d->catalogues.begin();
467 it != d->catalogues.end() && bRes;
468 ++it )
469 {
470 bRes = !catalogueFileName( language, *it ).isNull();
471 if ( !bRes )
472 kdDebug(173) << "message catalogue not found: "
473 << (*it).name() << endl;
474 }
475
476 return bRes;
477}
478
479bool KLocale::setLanguage(const QString & language)
480{
481 bool bRes = true;
482
483 if (d->first_language.isNull() || language != d->first_language)
484 bRes = isLanguageInstalled( language );
485
486 if ( bRes )
487 {
488 m_language = language;
489
490 // remember our first time - it will be our true love
491 if (d->first_language.isNull())
492 d->first_language = language;
493
494 doBindInit();
495 }
496
497 return bRes;
498}
499
500bool KLocale::setLanguage(const QStringList & languages)
501{
502 QStringList languageList(languages);
503
504 // Remove duplicate entries in reverse so that we
505 // can keep user's language preference order intact. (DA)
506 for( QStringList::Iterator it = languageList.fromLast();
507 it != languageList.begin();
508 --it )
509 if ( languageList.contains(*it) > 1 || (*it).isEmpty() )
510 it = languageList.remove( it );
511
512 bool bRes = false;
513 for ( QStringList::ConstIterator it = languageList.begin();
514 it != languageList.end();
515 ++it )
516 if ( bRes = setLanguage( *it ) )
517 break;
518
519 if ( !bRes )
520 setLanguage(defaultLanguage());
521
522 d->languageList = languageList;
523 d->langTwoAlpha.clear(); // Flush cache
524
525 return bRes;
526}
527
528void KLocale::splitLocale(const QString & aStr,
529 QString & language,
530 QString & country,
531 QString & chrset)
532{
533 QString str = aStr;
534
535 // just in case, there is another language appended
536 int f = str.find(':');
537 if (f >= 0)
538 str.truncate(f);
539
540 country = QString::null;
541 chrset = QString::null;
542 language = QString::null;
543
544 f = str.find('.');
545 if (f >= 0)
546 {
547 chrset = str.mid(f + 1);
548 str.truncate(f);
549 }
550
551 f = str.find('_');
552 if (f >= 0)
553 {
554 country = str.mid(f + 1);
555 str.truncate(f);
556 }
557
558 language = str;
559}
560
561QString KLocale::language() const
562{
563 return m_language;
564}
565
566QString KLocale::country() const
567{
568 return m_country;
569}
570
571QString KLocale::monthName(int i, bool shortName) const
572{
573 if ( shortName )
574 switch ( i )
575 {
576 case 1: return translate("January", "Jan");
577 case 2: return translate("February", "Feb");
578 case 3: return translate("March", "Mar");
579 case 4: return translate("April", "Apr");
580 case 5: return translate("May short", "May");
581 case 6: return translate("June", "Jun");
582 case 7: return translate("July", "Jul");
583 case 8: return translate("August", "Aug");
584 case 9: return translate("September", "Sep");
585 case 10: return translate("October", "Oct");
586 case 11: return translate("November", "Nov");
587 case 12: return translate("December", "Dec");
588 }
589 else
590 switch (i)
591 {
592 case 1: return translate("January");
593 case 2: return translate("February");
594 case 3: return translate("March");
595 case 4: return translate("April");
596 case 5: return translate("May long", "May");
597 case 6: return translate("June");
598 case 7: return translate("July");
599 case 8: return translate("August");
600 case 9: return translate("September");
601 case 10: return translate("October");
602 case 11: return translate("November");
603 case 12: return translate("December");
604 }
605
606 return QString::null;
607}
608
609QString KLocale::monthNamePossessive(int i, bool shortName) const
610{
611 if ( shortName )
612 switch ( i )
613 {
614 case 1: return translate("of January", "of Jan");
615 case 2: return translate("of February", "of Feb");
616 case 3: return translate("of March", "of Mar");
617 case 4: return translate("of April", "of Apr");
618 case 5: return translate("of May short", "of May");
619 case 6: return translate("of June", "of Jun");
620 case 7: return translate("of July", "of Jul");
621 case 8: return translate("of August", "of Aug");
622 case 9: return translate("of September", "of Sep");
623 case 10: return translate("of October", "of Oct");
624 case 11: return translate("of November", "of Nov");
625 case 12: return translate("of December", "of Dec");
626 }
627 else
628 switch (i)
629 {
630 case 1: return translate("of January");
631 case 2: return translate("of February");
632 case 3: return translate("of March");
633 case 4: return translate("of April");
634 case 5: return translate("of May long", "of May");
635 case 6: return translate("of June");
636 case 7: return translate("of July");
637 case 8: return translate("of August");
638 case 9: return translate("of September");
639 case 10: return translate("of October");
640 case 11: return translate("of November");
641 case 12: return translate("of December");
642 }
643
644 return QString::null;
645}
646
647QString KLocale::weekDayName (int i, bool shortName) const
648{
649 if ( shortName )
650 switch ( i )
651 {
652 case 1: return translate("Monday", "Mon");
653 case 2: return translate("Tuesday", "Tue");
654 case 3: return translate("Wednesday", "Wed");
655 case 4: return translate("Thursday", "Thu");
656 case 5: return translate("Friday", "Fri");
657 case 6: return translate("Saturday", "Sat");
658 case 7: return translate("Sunday", "Sun");
659 }
660 else
661 switch ( i )
662 {
663 case 1: return translate("Monday");
664 case 2: return translate("Tuesday");
665 case 3: return translate("Wednesday");
666 case 4: return translate("Thursday");
667 case 5: return translate("Friday");
668 case 6: return translate("Saturday");
669 case 7: return translate("Sunday");
670 }
671
672 return QString::null;
673}
674
675void KLocale::insertCatalogue( const QString & catalogue )
676{
677 KCatalogue cat( catalogue );
678
679 initCatalogue( cat );
680
681 d->catalogues.append( cat );
682}
683
684void KLocale::removeCatalogue(const QString &catalogue)
685{
686 for ( QValueList<KCatalogue>::Iterator it = d->catalogues.begin();
687 it != d->catalogues.end(); )
688 if ((*it).name() == catalogue) {
689 it = d->catalogues.remove(it);
690 return;
691 } else
692 ++it;
693}
694
695void KLocale::setActiveCatalogue(const QString &catalogue)
696{
697 for ( QValueList<KCatalogue>::Iterator it = d->catalogues.begin();
698 it != d->catalogues.end(); ++it)
699 if ((*it).name() == catalogue) {
700 KCatalogue save = *it;
701 d->catalogues.remove(it);
702 d->catalogues.prepend(save);
703 return;
704 }
705}
706
707KLocale::~KLocale()
708{
709 delete d->languages;
710 delete d;
711}
712
713QString KLocale::translate_priv(const char *msgid,
714 const char *fallback,
715 const char **translated) const
716{
717 if (!msgid || !msgid[0])
718 {
719 kdWarning() << "KLocale: trying to look up \"\" in catalogue. "
720 << "Fix the program" << endl;
721 return QString::null;
722 }
723
724 if ( useDefaultLanguage() )
725 return QString::fromUtf8( fallback );
726
727 for ( QValueList<KCatalogue>::ConstIterator it = d->catalogues.begin();
728 it != d->catalogues.end();
729 ++it )
730 {
731 // kdDebug(173) << "translate " << msgid << " " << (*it).name() << " " << (!KGlobal::activeInstance() ? QCString("no instance") : KGlobal::activeInstance()->instanceName()) << endl;
732 const char * text = (*it).translate( msgid );
733
734 if ( text )
735 {
736 // we found it
737 if (translated)
738 *translated = text;
739 return QString::fromUtf8( text );
740 }
741 }
742
743 // Always use UTF-8 if the string was not found
744 return QString::fromUtf8( fallback );
745}
746
747QString KLocale::translate(const char* msgid) const
748{
749 return translate_priv(msgid, msgid);
750}
751
752QString KLocale::translate( const char *index, const char *fallback) const
753{
754 if (!index || !index[0] || !fallback || !fallback[0])
755 {
756 kdDebug(173) << "KLocale: trying to look up \"\" in catalogue. "
757 << "Fix the program" << endl;
758 return QString::null;
759 }
760
761 if ( useDefaultLanguage() )
762 return QString::fromUtf8( fallback );
763
764 char *newstring = new char[strlen(index) + strlen(fallback) + 5];
765 sprintf(newstring, "_: %s\n%s", index, fallback);
766 // as copying QString is very fast, it looks slower as it is ;/
767 QString r = translate_priv(newstring, fallback);
768 delete [] newstring;
769
770 return r;
771}
772
773static QString put_n_in(const QString &orig, unsigned long n)
774{
775 QString ret = orig;
776 int index = ret.find("%n");
777 if (index == -1)
778 return ret;
779 ret.replace(index, 2, QString::number(n));
780 return ret;
781}
782
783#define EXPECT_LENGTH(x) \
784 if (forms.count() != x) { \
785 kdError() << "translation of \"" << singular << "\" doesn't contain " << x << " different plural forms as expected\n"; \
786 return QString( "BROKEN TRANSLATION %1" ).arg( singular ); }
787
788QString KLocale::translate( const char *singular, const char *plural,
789 unsigned long n ) const
790{
791 if (!singular || !singular[0] || !plural || !plural[0])
792 {
793 kdWarning() << "KLocale: trying to look up \"\" in catalogue. "
794 << "Fix the program" << endl;
795 return QString::null;
796 }
797
798 char *newstring = new char[strlen(singular) + strlen(plural) + 6];
799 sprintf(newstring, "_n: %s\n%s", singular, plural);
800 // as copying QString is very fast, it looks slower as it is ;/
801 QString r = translate_priv(newstring, 0);
802 delete [] newstring;
803
804 if ( r.isEmpty() || useDefaultLanguage() || d->plural_form == -1) {
805 if ( n == 1 ) {
806 return put_n_in( QString::fromUtf8( singular ), n );
807 } else {
808 QString tmp = QString::fromUtf8( plural );
809#ifndef NDEBUG
810 if (tmp.find("%n") == -1) {
811 kdWarning() << "the message for i18n should contain a '%n'! " << plural << endl;
812 }
813#endif
814 return put_n_in( tmp, n );
815 }
816 }
817
818 QStringList forms = QStringList::split( "\n", r, false );
819 switch ( d->plural_form ) {
820 case 0: // NoPlural
821 EXPECT_LENGTH( 1 );
822 return put_n_in( forms[0], n);
823 case 1: // TwoForms
824 EXPECT_LENGTH( 2 );
825 if ( n == 1 )
826 return put_n_in( forms[0], n);
827 else
828 return put_n_in( forms[1], n);
829 case 2: // French
830 EXPECT_LENGTH( 2 );
831 if ( n == 1 || n == 0 )
832 return put_n_in( forms[0], n);
833 else
834 return put_n_in( forms[1], n);
835 case 3: // Gaeilge
836 EXPECT_LENGTH( 3 );
837 if ( n == 1 )
838 return put_n_in( forms[0], n);
839 else if ( n == 2 )
840 return put_n_in( forms[1], n);
841 else
842 return put_n_in( forms[2], n);
843 case 4: // Russian, corrected by mok
844 EXPECT_LENGTH( 3 );
845 if ( n%10 == 1 && n%100 != 11)
846 return put_n_in( forms[0], n); // odin fail
847 else if (( n%10 >= 2 && n%10 <=4 ) && (n%100<10 || n%100>20))
848 return put_n_in( forms[1], n); // dva faila
849 else
850 return put_n_in( forms[2], n); // desyat' failov
851 case 5: // Polish
852 EXPECT_LENGTH( 3 );
853 if ( n == 1 )
854 return put_n_in( forms[0], n);
855 else if ( n%10 >= 2 && n%10 <=4 && (n%100<10 || n%100>=20) )
856 return put_n_in( forms[1], n);
857 else
858 return put_n_in( forms[2], n);
859 case 6: // Slovenian
860 EXPECT_LENGTH( 4 );
861 if ( n%100 == 1 )
862 return put_n_in( forms[1], n); // ena datoteka
863 else if ( n%100 == 2 )
864 return put_n_in( forms[2], n); // dve datoteki
865 else if ( n%100 == 3 || n%100 == 4 )
866 return put_n_in( forms[3], n); // tri datoteke
867 else
868 return put_n_in( forms[0], n); // sto datotek
869 case 7: // Lithuanian
870 EXPECT_LENGTH( 3 );
871 if ( n%10 == 0 || (n%100>=11 && n%100<=19) )
872 return put_n_in( forms[2], n);
873 else if ( n%10 == 1 )
874 return put_n_in( forms[0], n);
875 else
876 return put_n_in( forms[1], n);
877 case 8: // Czech
878 EXPECT_LENGTH( 3 );
879 if ( n%100 == 1 )
880 return put_n_in( forms[0], n);
881 else if (( n%100 >= 2 ) && ( n%100 <= 4 ))
882 return put_n_in( forms[1], n);
883 else
884 return put_n_in( forms[2], n);
885 case 9: // Slovak
886 EXPECT_LENGTH( 3 );
887 if ( n == 1 )
888 return put_n_in( forms[0], n);
889 else if (( n >= 2 ) && ( n <= 4 ))
890 return put_n_in( forms[1], n);
891 else
892 return put_n_in( forms[2], n);
893 case 10: // Maltese
894 EXPECT_LENGTH( 4 );
895 if ( n == 1 )
896 return put_n_in( forms[0], n );
897 else if ( ( n == 0 ) || ( n%100 > 0 && n%100 <= 10 ) )
898 return put_n_in( forms[1], n );
899 else if ( n%100 > 10 && n%100 < 20 )
900 return put_n_in( forms[2], n );
901 else
902 return put_n_in( forms[3], n );
903 case 11: // Arabic
904 EXPECT_LENGTH( 4 );
905 if (n == 1)
906 return put_n_in(forms[0], n);
907 else if (n == 2)
908 return put_n_in(forms[1], n);
909 else if ( n < 11)
910 return put_n_in(forms[2], n);
911 else
912 return put_n_in(forms[3], n);
913 case 12: // Balcan
914 EXPECT_LENGTH( 3 );
915 if (n != 11 && n % 10 == 1)
916 return put_n_in(forms[0], n);
917 else if (n / 10 != 1 && n % 10 >= 2 && n % 10 <= 4)
918 return put_n_in(forms[1], n);
919 else
920 return put_n_in(forms[2], n);
921 }
922 kdError() << "The function should have been returned in another way\n";
923
924 return QString::null;
925}
926
927QString KLocale::translateQt( const char *context, const char *source,
928 const char *message) const
929{
930 if (!source || !source[0]) {
931 kdWarning() << "KLocale: trying to look up \"\" in catalogue. "
932 << "Fix the program" << endl;
933 return QString::null;
934 }
935
936 if ( useDefaultLanguage() ) {
937 return QString::null;
938 }
939
940 char *newstring = 0;
941 const char *translation = 0;
942 QString r;
943
944 if ( message && message[0]) {
945 char *newstring = new char[strlen(source) + strlen(message) + 5];
946 sprintf(newstring, "_: %s\n%s", source, message);
947 const char *translation = 0;
948 // as copying QString is very fast, it looks slower as it is ;/
949 r = translate_priv(newstring, source, &translation);
950 delete [] newstring;
951 if (translation)
952 return r;
953 }
954
955 if ( context && context[0] && message && message[0]) {
956 newstring = new char[strlen(context) + strlen(message) + 5];
957 sprintf(newstring, "_: %s\n%s", context, message);
958 // as copying QString is very fast, it looks slower as it is ;/
959 r = translate_priv(newstring, source, &translation);
960 delete [] newstring;
961 if (translation)
962 return r;
963 }
964
965 r = translate_priv(source, source, &translation);
966 if (translation)
967 return r;
968 return QString::null;
969}
970
971bool KLocale::nounDeclension() const
972{
973 doFormatInit();
974 return d->nounDeclension;
975}
976
977bool KLocale::dateMonthNamePossessive() const
978{
979 doFormatInit();
980 return d->dateMonthNamePossessive;
981}
982
983int KLocale::weekStartDay() const
984{
985 doFormatInit();
986 return d->weekStartDay;
987}
988
989bool KLocale::weekStartsMonday() const //deprecated
990{
991 doFormatInit();
992 return (d->weekStartDay==1);
993}
994
995QString KLocale::decimalSymbol() const
996{
997 doFormatInit();
998 return m_decimalSymbol;
999}
1000
1001QString KLocale::thousandsSeparator() const
1002{
1003 doFormatInit();
1004 return m_thousandsSeparator;
1005}
1006
1007QString KLocale::currencySymbol() const
1008{
1009 doFormatInit();
1010 return m_currencySymbol;
1011}
1012
1013QString KLocale::monetaryDecimalSymbol() const
1014{
1015 doFormatInit();
1016 return m_monetaryDecimalSymbol;
1017}
1018
1019QString KLocale::monetaryThousandsSeparator() const
1020{
1021 doFormatInit();
1022 return m_monetaryThousandsSeparator;
1023}
1024
1025QString KLocale::positiveSign() const
1026{
1027 doFormatInit();
1028 return m_positiveSign;
1029}
1030
1031QString KLocale::negativeSign() const
1032{
1033 doFormatInit();
1034 return m_negativeSign;
1035}
1036
1037int KLocale::fracDigits() const
1038{
1039 doFormatInit();
1040 return m_fracDigits;
1041}
1042
1043bool KLocale::positivePrefixCurrencySymbol() const
1044{
1045 doFormatInit();
1046 return m_positivePrefixCurrencySymbol;
1047}
1048
1049bool KLocale::negativePrefixCurrencySymbol() const
1050{
1051 doFormatInit();
1052 return m_negativePrefixCurrencySymbol;
1053}
1054
1055KLocale::SignPosition KLocale::positiveMonetarySignPosition() const
1056{
1057 doFormatInit();
1058 return m_positiveMonetarySignPosition;
1059}
1060
1061KLocale::SignPosition KLocale::negativeMonetarySignPosition() const
1062{
1063 doFormatInit();
1064 return m_negativeMonetarySignPosition;
1065}
1066
1067static inline void put_it_in( QChar *buffer, uint& index, const QString &s )
1068{
1069 for ( uint l = 0; l < s.length(); l++ )
1070 buffer[index++] = s.at( l );
1071}
1072
1073static inline void put_it_in( QChar *buffer, uint& index, int number )
1074{
1075 buffer[index++] = number / 10 + '0';
1076 buffer[index++] = number % 10 + '0';
1077}
1078
1079QString KLocale::formatMoney(double num,
1080 const QString & symbol,
1081 int precision) const
1082{
1083 // some defaults
1084 QString currency = symbol.isNull()
1085 ? currencySymbol()
1086 : symbol;
1087 if (precision < 0) precision = fracDigits();
1088
1089 // the number itself
1090 bool neg = num < 0;
1091 QString res = QString::number(neg?-num:num, 'f', precision);
1092 int pos = res.find('.');
1093 if (pos == -1) pos = res.length();
1094 else res.replace(pos, 1, monetaryDecimalSymbol());
1095
1096 while (0 < (pos -= 3))
1097 res.insert(pos, monetaryThousandsSeparator()); // thousend sep
1098
1099 // set some variables we need later
1100 int signpos = neg
1101 ? negativeMonetarySignPosition()
1102 : positiveMonetarySignPosition();
1103 QString sign = neg
1104 ? negativeSign()
1105 : positiveSign();
1106
1107 switch (signpos)
1108 {
1109 case ParensAround:
1110 res.prepend('(');
1111 res.append (')');
1112 break;
1113 case BeforeQuantityMoney:
1114 res.prepend(sign);
1115 break;
1116 case AfterQuantityMoney:
1117 res.append(sign);
1118 break;
1119 case BeforeMoney:
1120 currency.prepend(sign);
1121 break;
1122 case AfterMoney:
1123 currency.append(sign);
1124 break;
1125 }
1126
1127 if (neg?negativePrefixCurrencySymbol():
1128 positivePrefixCurrencySymbol())
1129 {
1130 res.prepend(' ');
1131 res.prepend(currency);
1132 } else {
1133 res.append (' ');
1134 res.append (currency);
1135 }
1136
1137 return res;
1138}
1139
1140QString KLocale::formatMoney(const QString &numStr) const
1141{
1142 return formatMoney(numStr.toDouble());
1143}
1144
1145QString KLocale::formatNumber(double num, int precision) const
1146{
1147 bool neg = num < 0;
1148 if (precision == -1) precision = 2;
1149 QString res = QString::number(neg?-num:num, 'f', precision);
1150 int pos = res.find('.');
1151 if (pos == -1) pos = res.length();
1152 else res.replace(pos, 1, decimalSymbol());
1153
1154 while (0 < (pos -= 3))
1155 res.insert(pos, thousandsSeparator()); // thousand sep
1156
1157 // How can we know where we should put the sign?
1158 res.prepend(neg?negativeSign():positiveSign());
1159
1160 return res;
1161}
1162
1163QString KLocale::formatLong(long num) const
1164{
1165 return formatNumber((double)num, 0);
1166}
1167
1168QString KLocale::formatNumber(const QString &numStr) const
1169{
1170 return formatNumber(numStr.toDouble());
1171}
1172
1173QString KLocale::formatDate(const QDate &pDate, bool shortFormat) const
1174{
1175 const QString rst = shortFormat?dateFormatShort():dateFormat();
1176
1177 // I'm rather safe than sorry
1178 QChar *buffer = new QChar[rst.length() * 3 / 2 + 50];
1179
1180 unsigned int index = 0;
1181 bool escape = false;
1182 int number = 0;
1183
1184 int year = calendar()->year(pDate);
1185 int month = calendar()->month(pDate);
1186 int day = calendar()->day(pDate);
1187
1188 for ( uint format_index = 0; format_index < rst.length(); ++format_index )
1189 {
1190 if ( !escape )
1191 {
1192 if ( rst.at( format_index ).unicode() == '%' )
1193 escape = true;
1194 else
1195 buffer[index++] = rst.at( format_index );
1196 }
1197 else
1198 {
1199 switch ( rst.at( format_index ).unicode() )
1200 {
1201 case '%':
1202 buffer[index++] = '%';
1203 break;
1204 case 'Y':
1205 put_it_in( buffer, index, year / 100 );
1206 case 'y':
1207 put_it_in( buffer, index, year % 100 );
1208 break;
1209 case 'n':
1210 number = month;
1211 case 'e':
1212 // to share the code
1213 if ( rst.at( format_index ).unicode() == 'e' )
1214 number = day;
1215 if ( number / 10 )
1216 buffer[index++] = number / 10 + '0';
1217 buffer[index++] = number % 10 + '0';
1218 break;
1219 case 'm':
1220 put_it_in( buffer, index, month );
1221 break;
1222 case 'b':
1223 if (d->nounDeclension && d->dateMonthNamePossessive)
1224 //US put_it_in( buffer, index, calendar()->monthNamePossessive(month, year, true) );
1225 put_it_in( buffer, index, calendar()->monthNamePossessive(month, true) );
1226 else
1227 //US put_it_in( buffer, index, calendar()->monthName(month, year, true) );
1228 put_it_in( buffer, index, calendar()->monthName(month, true) );
1229 break;
1230 case 'B':
1231 if (d->nounDeclension && d->dateMonthNamePossessive)
1232 //US put_it_in( buffer, index, calendar()->monthNamePossessive(month, year, false) );
1233 put_it_in( buffer, index, calendar()->monthNamePossessive(month, false) );
1234 else
1235 //US put_it_in( buffer, index, calendar()->monthName(month, year, false) );
1236 put_it_in( buffer, index, calendar()->monthName(month, false) );
1237 break;
1238 case 'd':
1239 put_it_in( buffer, index, day );
1240 break;
1241 case 'a':
1242 put_it_in( buffer, index, calendar()->weekDayName(pDate, true) );
1243 break;
1244 case 'A':
1245 put_it_in( buffer, index, calendar()->weekDayName(pDate, false) );
1246 break;
1247 default:
1248 buffer[index++] = rst.at( format_index );
1249 break;
1250 }
1251 escape = false;
1252 }
1253 }
1254 QString ret( buffer, index );
1255 delete [] buffer;
1256 return ret;
1257}
1258
1259void KLocale::setMainCatalogue(const char *catalogue)
1260{
1261 maincatalogue = catalogue;
1262}
1263
1264double KLocale::readNumber(const QString &_str, bool * ok) const
1265{
1266 QString str = _str.stripWhiteSpace();
1267 bool neg = str.find(negativeSign()) == 0;
1268 if (neg)
1269 str.remove( 0, negativeSign().length() );
1270
1271 /* will hold the scientific notation portion of the number.
1272 Example, with 2.34E+23, exponentialPart == "E+23"
1273 */
1274 QString exponentialPart;
1275 int EPos;
1276
1277 EPos = str.find('E', 0, false);
1278
1279 if (EPos != -1)
1280 {
1281 exponentialPart = str.mid(EPos);
1282 str = str.left(EPos);
1283 }
1284
1285 int pos = str.find(decimalSymbol());
1286 QString major;
1287 QString minor;
1288 if ( pos == -1 )
1289 major = str;
1290 else
1291 {
1292 major = str.left(pos);
1293 minor = str.mid(pos + decimalSymbol().length());
1294 }
1295
1296 // Remove thousand separators
1297 int thlen = thousandsSeparator().length();
1298 int lastpos = 0;
1299 while ( ( pos = major.find( thousandsSeparator() ) ) > 0 )
1300 {
1301 // e.g. 12,,345,,678,,922 Acceptable positions (from the end) are 5, 10, 15... i.e. (3+thlen)*N
1302 int fromEnd = major.length() - pos;
1303 if ( fromEnd % (3+thlen) != 0 // Needs to be a multiple, otherwise it's an error
1304 || pos - lastpos > 3 // More than 3 digits between two separators -> error
1305 || pos == 0 // Can't start with a separator
1306 || (lastpos>0 && pos-lastpos!=3)) // Must have exactly 3 digits between two separators
1307 {
1308 if (ok) *ok = false;
1309 return 0.0;
1310 }
1311
1312 lastpos = pos;
1313 major.remove( pos, thlen );
1314 }
1315 if (lastpos>0 && major.length()-lastpos!=3) // Must have exactly 3 digits after the last separator
1316 {
1317 if (ok) *ok = false;
1318 return 0.0;
1319 }
1320
1321 QString tot;
1322 if (neg) tot = '-';
1323
1324 tot += major + '.' + minor + exponentialPart;
1325
1326 return tot.toDouble(ok);
1327}
1328
1329double KLocale::readMoney(const QString &_str, bool * ok) const
1330{
1331 QString str = _str.stripWhiteSpace();
1332 bool neg = false;
1333 bool currencyFound = false;
1334 // First try removing currency symbol from either end
1335 int pos = str.find(currencySymbol());
1336 if ( pos == 0 || pos == (int) str.length()-1 )
1337 {
1338 str.remove(pos,currencySymbol().length());
1339 str = str.stripWhiteSpace();
1340 currencyFound = true;
1341 }
1342 if (str.isEmpty())
1343 {
1344 if (ok) *ok = false;
1345 return 0;
1346 }
1347 // Then try removing negative sign from either end
1348 // (with a special case for parenthesis)
1349 if (negativeMonetarySignPosition() == ParensAround)
1350 {
1351 if (str.at(0) == '(' && str.at(str.length()-1) == ')')
1352 {
1353 neg = true;
1354 str.remove(str.length()-1,1);
1355 str.remove(0,1);
1356 }
1357 }
1358 else
1359 {
1360 int i1 = str.find(negativeSign());
1361 if ( i1 == 0 || i1 == (int) str.length()-1 )
1362 {
1363 neg = true;
1364 str.remove(i1,negativeSign().length());
1365 }
1366 }
1367 if (neg) str = str.stripWhiteSpace();
1368
1369 // Finally try again for the currency symbol, if we didn't find
1370 // it already (because of the negative sign being in the way).
1371 if ( !currencyFound )
1372 {
1373 pos = str.find(currencySymbol());
1374 if ( pos == 0 || pos == (int) str.length()-1 )
1375 {
1376 str.remove(pos,currencySymbol().length());
1377 str = str.stripWhiteSpace();
1378 }
1379 }
1380
1381 // And parse the rest as a number
1382 pos = str.find(monetaryDecimalSymbol());
1383 QString major;
1384 QString minior;
1385 if (pos == -1)
1386 major = str;
1387 else
1388 {
1389 major = str.left(pos);
1390 minior = str.mid(pos + monetaryDecimalSymbol().length());
1391 }
1392
1393 // Remove thousand separators
1394 int thlen = monetaryThousandsSeparator().length();
1395 int lastpos = 0;
1396 while ( ( pos = major.find( monetaryThousandsSeparator() ) ) > 0 )
1397 {
1398 // e.g. 12,,345,,678,,922 Acceptable positions (from the end) are 5, 10, 15... i.e. (3+thlen)*N
1399 int fromEnd = major.length() - pos;
1400 if ( fromEnd % (3+thlen) != 0 // Needs to be a multiple, otherwise it's an error
1401 || pos - lastpos > 3 // More than 3 digits between two separators -> error
1402 || pos == 0 // Can't start with a separator
1403 || (lastpos>0 && pos-lastpos!=3)) // Must have exactly 3 digits between two separators
1404 {
1405 if (ok) *ok = false;
1406 return 0.0;
1407 }
1408 lastpos = pos;
1409 major.remove( pos, thlen );
1410 }
1411 if (lastpos>0 && major.length()-lastpos!=3) // Must have exactly 3 digits after the last separator
1412 {
1413 if (ok) *ok = false;
1414 return 0.0;
1415 }
1416
1417 QString tot;
1418 if (neg) tot = '-';
1419 tot += major + '.' + minior;
1420 return tot.toDouble(ok);
1421}
1422
1423/**
1424 * helper function to read integers
1425 * @param str
1426 * @param pos the position to start at. It will be updated when we parse it.
1427 * @return the integer read in the string, or -1 if no string
1428 */
1429static int readInt(const QString &str, uint &pos)
1430{
1431 if (!str.at(pos).isDigit()) return -1;
1432 int result = 0;
1433 for (; str.length() > pos && str.at(pos).isDigit(); pos++)
1434 {
1435 result *= 10;
1436 result += str.at(pos).digitValue();
1437 }
1438
1439 return result;
1440}
1441
1442QDate KLocale::readDate(const QString &intstr, bool* ok) const
1443{
1444 QDate date;
1445 date = readDate(intstr, ShortFormat, ok);
1446 if (date.isValid()) return date;
1447 return readDate(intstr, NormalFormat, ok);
1448}
1449
1450QDate KLocale::readDate(const QString &intstr, ReadDateFlags flags, bool* ok) const
1451{
1452 QString fmt = ((flags & ShortFormat) ? dateFormatShort() : dateFormat()).simplifyWhiteSpace();
1453 return readDate( intstr, fmt, ok );
1454}
1455
1456QDate KLocale::readDate(const QString &intstr, const QString &fmt, bool* ok) const
1457{
1458 //kdDebug() << "KLocale::readDate intstr=" << intstr << " fmt=" << fmt << endl;
1459 QString str = intstr.simplifyWhiteSpace().lower();
1460 int day = -1, month = -1;
1461 // allow the year to be omitted if not in the format
1462 int year = calendar()->year(QDate::currentDate());
1463 uint strpos = 0;
1464 uint fmtpos = 0;
1465
1466 bool error = false;
1467
1468 while (fmt.length() > fmtpos && str.length() > strpos && !error)
1469 {
1470
1471 QChar c = fmt.at(fmtpos++);
1472
1473 if (c != '%') {
1474 if (c.isSpace() && str.at(strpos).isSpace())
1475 strpos++;
1476 else if (c != str.at(strpos++))
1477 error = true;
1478 }
1479 else
1480 {
1481 int j;
1482 // remove space at the begining
1483 if (str.length() > strpos && str.at(strpos).isSpace())
1484 strpos++;
1485
1486 c = fmt.at(fmtpos++);
1487 switch (c)
1488 {
1489 case 'a':
1490 case 'A':
1491
1492 error = true;
1493 j = 1;
1494 while (error && (j < 8)) {
1495 QString s = weekDayName(j, c == 'a').lower();
1496 int len = s.length();
1497 if (str.mid(strpos, len) == s)
1498 {
1499 strpos += len;
1500 error = false;
1501 }
1502 j++;
1503 }
1504 break;
1505 case 'b':
1506 case 'B':
1507
1508 error = true;
1509 if (d->nounDeclension && d->dateMonthNamePossessive) {
1510 j = 1;
1511 while (error && (j < 13)) {
1512 //US QString s = calendar()->monthNamePossessive(j, year, c == 'b').lower();
1513 QString s = calendar()->monthNamePossessive(j, c == 'b').lower();
1514 int len = s.length();
1515 if (str.mid(strpos, len) == s) {
1516 month = j;
1517 strpos += len;
1518 error = false;
1519 }
1520 j++;
1521 }
1522 }
1523 j = 1;
1524 while (error && (j < 13)) {
1525 //US QString s = calendar()->monthName(j, year, c == 'b').lower();
1526 QString s = calendar()->monthName(j, c == 'b').lower();
1527 int len = s.length();
1528 if (str.mid(strpos, len) == s) {
1529 month = j;
1530 strpos += len;
1531 error = false;
1532 }
1533 j++;
1534 }
1535 break;
1536 case 'd':
1537 case 'e':
1538 day = readInt(str, strpos);
1539 error = (day < 1 || day > 31);
1540 break;
1541
1542 case 'n':
1543 case 'm':
1544 month = readInt(str, strpos);
1545 error = (month < 1 || month > 12);
1546 break;
1547
1548 case 'Y':
1549 case 'y':
1550 year = readInt(str, strpos);
1551 error = (year < 0);
1552 // Qt treats a year in the range 0-100 as 1900-1999.
1553 // It is nicer for the user if we treat 0-68 as 2000-2068
1554 if (c == 'y' && year < 69)
1555 // eg. gregorian += 2000
1556 year += (calendar()->year(QDate::currentDate()) / 100) * 100;
1557 else if (c == 'y' && year < 100)
1558 // eg. gregorian += 1900
1559 year += (calendar()->year(QDate::currentDate()) / 100) * 100 - 100;
1560 break;
1561 }
1562 }
1563 }
1564
1565 /* for a match, we should reach the end of both strings, not just one of
1566 them */
1567 if ( fmt.length() > fmtpos || str.length() > strpos )
1568 {
1569 error = true;
1570 }
1571
1572 //kdDebug(173) << "KLocale::readDate day=" << day << " month=" << month << " year=" << year << endl;
1573 if ( year != -1 && month != -1 && day != -1 && !error)
1574 {
1575 if (ok) *ok = true;
1576
1577 QDate result;
1578 calendar()->setYMD(result, year, month, day);
1579
1580 return result;
1581 }
1582 else
1583 {
1584 if (ok) *ok = false;
1585 return QDate(); // invalid date
1586 }
1587}
1588
1589QTime KLocale::readTime(const QString &intstr, bool *ok) const
1590{
1591 QTime _time;
1592 _time = readTime(intstr, WithSeconds, ok);
1593 if (_time.isValid()) return _time;
1594 return readTime(intstr, WithoutSeconds, ok);
1595}
1596
1597QTime KLocale::readTime(const QString &intstr, ReadTimeFlags flags, bool *ok) const
1598{
1599 QString str = intstr.simplifyWhiteSpace().lower();
1600 QString Format = timeFormat().simplifyWhiteSpace();
1601 if (flags & WithoutSeconds)
1602 {
1603//US remove not available in my QT version
1604//US Format.remove(QRegExp(".%S"));
1605 Format.replace(QRegExp(".%S"), "");
1606 }
1607
1608 int hour = -1, minute = -1;
1609 int second = ( (flags & WithoutSeconds) == 0 ) ? -1 : 0; // don't require seconds
1610 bool g_12h = false;
1611 bool pm = false;
1612 uint strpos = 0;
1613 uint Formatpos = 0;
1614
1615 while (Format.length() > Formatpos || str.length() > strpos)
1616 {
1617 if ( !(Format.length() > Formatpos && str.length() > strpos) ) goto error;
1618
1619 QChar c = Format.at(Formatpos++);
1620
1621 if (c != '%')
1622 {
1623 if (c.isSpace())
1624 strpos++;
1625 else if (c != str.at(strpos++))
1626 goto error;
1627 continue;
1628 }
1629
1630 // remove space at the begining
1631 if (str.length() > strpos && str.at(strpos).isSpace())
1632 strpos++;
1633
1634 c = Format.at(Formatpos++);
1635 switch (c)
1636 {
1637 case 'p':
1638 {
1639 QString s;
1640 s = translate("pm").lower();
1641 int len = s.length();
1642 if (str.mid(strpos, len) == s)
1643 {
1644 pm = true;
1645 strpos += len;
1646 }
1647 else
1648 {
1649 s = translate("am").lower();
1650 len = s.length();
1651 if (str.mid(strpos, len) == s) {
1652 pm = false;
1653 strpos += len;
1654 }
1655 else
1656 goto error;
1657 }
1658 }
1659 break;
1660
1661 case 'k':
1662 case 'H':
1663 g_12h = false;
1664 hour = readInt(str, strpos);
1665 if (hour < 0 || hour > 23)
1666 goto error;
1667
1668 break;
1669
1670 case 'l':
1671 case 'I':
1672 g_12h = true;
1673 hour = readInt(str, strpos);
1674 if (hour < 1 || hour > 12)
1675 goto error;
1676
1677 break;
1678
1679 case 'M':
1680 minute = readInt(str, strpos);
1681 if (minute < 0 || minute > 59)
1682 goto error;
1683
1684 break;
1685
1686 case 'S':
1687 second = readInt(str, strpos);
1688 if (second < 0 || second > 59)
1689 goto error;
1690
1691 break;
1692 }
1693 }
1694 if (g_12h) {
1695 hour %= 12;
1696 if (pm) hour += 12;
1697 }
1698
1699 if (ok) *ok = true;
1700 return QTime(hour, minute, second);
1701
1702 error:
1703 if (ok) *ok = false;
1704 return QTime(-1, -1, -1); // return invalid date if it didn't work
1705}
1706
1707QString KLocale::formatTime(const QTime &pTime, bool includeSecs) const
1708{
1709 const QString rst = timeFormat();
1710
1711 // only "pm/am" here can grow, the rest shrinks, but
1712 // I'm rather safe than sorry
1713 QChar *buffer = new QChar[rst.length() * 3 / 2 + 30];
1714
1715 uint index = 0;
1716 bool escape = false;
1717 int number = 0;
1718
1719 for ( uint format_index = 0; format_index < rst.length(); format_index++ )
1720 {
1721 if ( !escape )
1722 {
1723 if ( rst.at( format_index ).unicode() == '%' )
1724 escape = true;
1725 else
1726 buffer[index++] = rst.at( format_index );
1727 }
1728 else
1729 {
1730 switch ( rst.at( format_index ).unicode() )
1731 {
1732 case '%':
1733 buffer[index++] = '%';
1734 break;
1735 case 'H':
1736 put_it_in( buffer, index, pTime.hour() );
1737 break;
1738 case 'I':
1739 put_it_in( buffer, index, ( pTime.hour() + 11) % 12 + 1 );
1740 break;
1741 case 'M':
1742 put_it_in( buffer, index, pTime.minute() );
1743 break;
1744 case 'S':
1745 if (includeSecs)
1746 put_it_in( buffer, index, pTime.second() );
1747 else if ( index > 0 )
1748 {
1749 // we remove the seperator sign before the seconds and
1750 // assume that works everywhere
1751 --index;
1752 break;
1753 }
1754 break;
1755 case 'k':
1756 number = pTime.hour();
1757 case 'l':
1758 // to share the code
1759 if ( rst.at( format_index ).unicode() == 'l' )
1760 number = (pTime.hour() + 11) % 12 + 1;
1761 if ( number / 10 )
1762 buffer[index++] = number / 10 + '0';
1763 buffer[index++] = number % 10 + '0';
1764 break;
1765 case 'p':
1766 {
1767 QString s;
1768 if ( pTime.hour() >= 12 )
1769 put_it_in( buffer, index, translate("pm") );
1770 else
1771 put_it_in( buffer, index, translate("am") );
1772 break;
1773 }
1774 default:
1775 buffer[index++] = rst.at( format_index );
1776 break;
1777 }
1778 escape = false;
1779 }
1780 }
1781 QString ret( buffer, index );
1782 delete [] buffer;
1783 return ret;
1784}
1785
1786bool KLocale::use12Clock() const
1787{
1788 if ((timeFormat().contains(QString::fromLatin1("%I")) > 0) ||
1789 (timeFormat().contains(QString::fromLatin1("%l")) > 0))
1790 return true;
1791 else
1792 return false;
1793}
1794
1795QString KLocale::languages() const
1796{
1797 return d->languageList.join( QString::fromLatin1(":") );
1798}
1799
1800QStringList KLocale::languageList() const
1801{
1802 return d->languageList;
1803}
1804
1805QString KLocale::formatDateTime(const QDateTime &pDateTime,
1806 bool shortFormat,
1807 bool includeSeconds) const
1808{
1809 return translate("concatenation of dates and time", "%1 %2")
1810 .arg( formatDate( pDateTime.date(), shortFormat ) )
1811 .arg( formatTime( pDateTime.time(), includeSeconds ) );
1812}
1813
1814QString i18n(const char* text)
1815{
1816 /*
1817 register KLocale *instance = KGlobal::locale();
1818 if (instance)
1819 return instance->translate(text);
1820 */
1821 return QString::fromUtf8(text);
1822}
1823
1824QString i18n(const char* index, const char *text)
1825{
1826 /*
1827 register KLocale *instance = KGlobal::locale();
1828 if (instance)
1829 return instance->translate(index, text);
1830 */
1831 return QString::fromUtf8(text);
1832}
1833
1834QString i18n(const char* singular, const char* plural, unsigned long n)
1835{
1836 return (QString::fromUtf8(plural)); // hack! remove this line!
1837 register KLocale *instance = KGlobal::locale();
1838 if (instance)
1839 return instance->translate(singular, plural, n);
1840 if (n == 1)
1841 return put_n_in(QString::fromUtf8(singular), n);
1842 else
1843 return put_n_in(QString::fromUtf8(plural), n);
1844}
1845
1846void KLocale::initInstance()
1847{
1848 if (KGlobal::locale())
1849 return;
1850
1851/*US lets change the whole way how to create a KLocale
1852 KInstance *app = KGlobal::instance();
1853 if (app) {
1854 KGlobal::_locale = new KLocale(QString::fromLatin1(app->instanceName()));
1855
1856 // only do this for the global instance
1857 QTextCodec::setCodecForLocale(KGlobal::_locale->codecForEncoding());
1858 }
1859 else
1860 kdDebug(173) << "no app name available using KLocale - nothing to do\n";
1861*/
1862//US new implementation
1863 QString appname = KGlobal::getAppName();
1864 if (appname) {
1865 KLocale *l = new KLocale(appname);
1866 KGlobal::setLocale(l);
1867
1868 // only do this for the global instance
1869//US
1870//US QTextCodec::setCodecForLocale(KGlobal::locale())->codecForEncoding());
1871//US qt_set_locale_codec( KGlobal::locale()->codecForEncoding() );
1872 qDebug("KLocale::initInstance we have to do here something !!!");
1873 }
1874 else
1875 kdDebug(173) << "no app name available using KLocale - nothing to do\n";
1876
1877}
1878
1879QString KLocale::langLookup(const QString &fname, const char *rtype)
1880{
1881 QStringList search;
1882
1883 // assemble the local search paths
1884//US we have only one resourcedir. So use it !!
1885/*US original
1886 const QStringList localDoc = KGlobal::dirs()->resourceDirs(rtype);
1887 // look up the different languages
1888 for (int id=localDoc.count()-1; id >= 0; --id)
1889 {
1890 QStringList langs = KGlobal::locale()->languageList();
1891 langs.append( "en" );
1892 langs.remove( defaultLanguage() );
1893 QStringList::ConstIterator lang;
1894 for (lang = langs.begin(); lang != langs.end(); ++lang)
1895 search.append(QString("%1%2/%3").arg(localDoc[id]).arg(*lang).arg(fname));
1896 }
1897*/
1898//US new code
1899//US What is here correct??? const QString localDoc = KGlobal::dirs()->findResourceDir(rtype);
1900 const QString localDoc = rtype;
1901 // look up the different languages
1902 QStringList langs = KGlobal::locale()->languageList();
1903 langs.append( "en" );
1904 langs.remove( defaultLanguage() );
1905 QStringList::ConstIterator lang;
1906 for (lang = langs.begin(); lang != langs.end(); ++lang)
1907 search.append(QString("%1%2/%3").arg(localDoc).arg(*lang).arg(fname));
1908
1909 // try to locate the file
1910 QStringList::Iterator it;
1911 for (it = search.begin(); it != search.end(); ++it)
1912 {
1913 kdDebug(173) << "Looking for help in: " << *it << endl;
1914
1915 QFileInfo info(*it);
1916 if (info.exists() && info.isFile() && info.isReadable())
1917 return *it;
1918 }
1919
1920 return QString::null;
1921}
1922
1923bool KLocale::useDefaultLanguage() const
1924{
1925 return language() == defaultLanguage();
1926}
1927
1928void KLocale::initEncoding(KConfig *)
1929{
1930 const int mibDefault = 4; // ISO 8859-1
1931
1932 // This all made more sense when we still had the EncodingEnum config key.
1933 setEncoding( QTextCodec::codecForLocale()->mibEnum() );
1934
1935 if ( !d->codecForEncoding )
1936 {
1937 kdWarning(173) << " Defaulting to ISO 8859-1 encoding." << endl;
1938 setEncoding(mibDefault);
1939 }
1940
1941 ASSERT( d->codecForEncoding );
1942}
1943
1944void KLocale::initFileNameEncoding(KConfig *)
1945{
1946 // If the following environment variable is set, assume all filenames
1947 // are in UTF-8 regardless of the current C locale.
1948 d->utf8FileEncoding = getenv("KDE_UTF8_FILENAMES") != 0;
1949 if (d->utf8FileEncoding)
1950 {
1951 QFile::setEncodingFunction(KLocale::encodeFileNameUTF8);
1952 QFile::setDecodingFunction(KLocale::decodeFileNameUTF8);
1953 }
1954 // Otherwise, stay with QFile's default filename encoding functions
1955 // which, on Unix platforms, use the locale's codec.
1956}
1957
1958QCString KLocale::encodeFileNameUTF8( const QString & fileName )
1959{
1960 return fileName.utf8();
1961}
1962
1963QString KLocale::decodeFileNameUTF8( const QCString & localFileName )
1964{
1965 return QString::fromUtf8(localFileName);
1966}
1967
1968void KLocale::initCatalogue( KCatalogue & catalogue )
1969{
1970 catalogue.setFileName( catalogueFileName( language(), catalogue ) );
1971}
1972
1973void KLocale::setDateFormat(const QString & format)
1974{
1975 doFormatInit();
1976 m_dateFormat = format.stripWhiteSpace();
1977}
1978
1979void KLocale::setDateFormatShort(const QString & format)
1980{
1981 doFormatInit();
1982 m_dateFormatShort = format.stripWhiteSpace();
1983}
1984
1985void KLocale::setDateMonthNamePossessive(bool possessive)
1986{
1987 doFormatInit();
1988 d->dateMonthNamePossessive = possessive;
1989}
1990
1991void KLocale::setTimeFormat(const QString & format)
1992{
1993 doFormatInit();
1994 m_timeFormat = format.stripWhiteSpace();
1995}
1996
1997void KLocale::setWeekStartsMonday(bool start) //deprecated
1998{
1999 doFormatInit();
2000 if (start)
2001 d->weekStartDay = 1;
2002 else
2003 d->weekStartDay = 7;
2004}
2005
2006void KLocale::setWeekStartDay(int day)
2007{
2008 doFormatInit();
2009 if (day>7 || day<1)
2010 d->weekStartDay = 1; //Monday is default
2011 else
2012 d->weekStartDay = day;
2013}
2014
2015QString KLocale::dateFormat() const
2016{
2017 doFormatInit();
2018 return m_dateFormat;
2019}
2020
2021QString KLocale::dateFormatShort() const
2022{
2023 doFormatInit();
2024 return m_dateFormatShort;
2025}
2026
2027QString KLocale::timeFormat() const
2028{
2029 doFormatInit();
2030 return m_timeFormat;
2031}
2032
2033void KLocale::setDecimalSymbol(const QString & symbol)
2034{
2035 doFormatInit();
2036 m_decimalSymbol = symbol.stripWhiteSpace();
2037}
2038
2039void KLocale::setThousandsSeparator(const QString & separator)
2040{
2041 doFormatInit();
2042 // allow spaces here
2043 m_thousandsSeparator = separator;
2044}
2045
2046void KLocale::setPositiveSign(const QString & sign)
2047{
2048 doFormatInit();
2049 m_positiveSign = sign.stripWhiteSpace();
2050}
2051
2052void KLocale::setNegativeSign(const QString & sign)
2053{
2054 doFormatInit();
2055 m_negativeSign = sign.stripWhiteSpace();
2056}
2057
2058void KLocale::setPositiveMonetarySignPosition(SignPosition signpos)
2059{
2060 doFormatInit();
2061 m_positiveMonetarySignPosition = signpos;
2062}
2063
2064void KLocale::setNegativeMonetarySignPosition(SignPosition signpos)
2065{
2066 doFormatInit();
2067 m_negativeMonetarySignPosition = signpos;
2068}
2069
2070void KLocale::setPositivePrefixCurrencySymbol(bool prefix)
2071{
2072 doFormatInit();
2073 m_positivePrefixCurrencySymbol = prefix;
2074}
2075
2076void KLocale::setNegativePrefixCurrencySymbol(bool prefix)
2077{
2078 doFormatInit();
2079 m_negativePrefixCurrencySymbol = prefix;
2080}
2081
2082void KLocale::setFracDigits(int digits)
2083{
2084 doFormatInit();
2085 m_fracDigits = digits;
2086}
2087
2088void KLocale::setMonetaryThousandsSeparator(const QString & separator)
2089{
2090 doFormatInit();
2091 // allow spaces here
2092 m_monetaryThousandsSeparator = separator;
2093}
2094
2095void KLocale::setMonetaryDecimalSymbol(const QString & symbol)
2096{
2097 doFormatInit();
2098 m_monetaryDecimalSymbol = symbol.stripWhiteSpace();
2099}
2100
2101void KLocale::setCurrencySymbol(const QString & symbol)
2102{
2103 doFormatInit();
2104 m_currencySymbol = symbol.stripWhiteSpace();
2105}
2106
2107int KLocale::pageSize() const
2108{
2109 doFormatInit();
2110 return d->pageSize;
2111}
2112
2113void KLocale::setPageSize(int pageSize)
2114{
2115 // #### check if it's in range??
2116 doFormatInit();
2117 d->pageSize = pageSize;
2118}
2119
2120KLocale::MeasureSystem KLocale::measureSystem() const
2121{
2122 doFormatInit();
2123 return d->measureSystem;
2124}
2125
2126void KLocale::setMeasureSystem(MeasureSystem value)
2127{
2128 doFormatInit();
2129 d->measureSystem = value;
2130}
2131
2132QString KLocale::defaultLanguage()
2133{
2134 return QString::fromLatin1("en_US");
2135}
2136
2137QString KLocale::defaultCountry()
2138{
2139 return QString::fromLatin1("C");
2140}
2141
2142const char * KLocale::encoding() const
2143{
2144 return codecForEncoding()->name();
2145}
2146
2147int KLocale::encodingMib() const
2148{
2149 return codecForEncoding()->mibEnum();
2150}
2151
2152int KLocale::fileEncodingMib() const
2153{
2154 if (d->utf8FileEncoding)
2155 return 106;
2156 return codecForEncoding()->mibEnum();
2157}
2158
2159QTextCodec * KLocale::codecForEncoding() const
2160{
2161 return d->codecForEncoding;
2162}
2163
2164bool KLocale::setEncoding(int mibEnum)
2165{
2166 QTextCodec * codec = QTextCodec::codecForMib(mibEnum);
2167 if (codec)
2168 d->codecForEncoding = codec;
2169
2170 return codec != 0;
2171}
2172
2173QStringList KLocale::languagesTwoAlpha() const
2174{
2175 if (d->langTwoAlpha.count())
2176 return d->langTwoAlpha;
2177
2178 const QStringList &origList = languageList();
2179
2180 QStringList result;
2181
2182//US KConfig config(QString::fromLatin1("language.codes"), true, false);
2183 KConfig config(locateLocal("config", QString::fromLatin1("language.codes")));
2184 config.setGroup("TwoLetterCodes");
2185
2186 for ( QStringList::ConstIterator it = origList.begin();
2187 it != origList.end();
2188 ++it )
2189 {
2190 QString lang = *it;
2191 QStringList langLst;
2192
2193/*US I changed the following code, because hasKey is not available.
2194!!! check if my version is correct
2195 if (config.hasKey( lang ))
2196 langLst = config.readListEntry( lang );
2197 else
2198 {
2199 int i = lang.find('_');
2200 if (i >= 0)
2201 lang.truncate(i);
2202 langLst << lang;
2203 }
2204*/
2205 langLst = config.readListEntry( lang );
2206 if (langLst.isEmpty())
2207 {
2208 int i = lang.find('_');
2209 if (i >= 0)
2210 lang.truncate(i);
2211 langLst << lang;
2212 }
2213
2214
2215 for ( QStringList::ConstIterator langIt = langLst.begin();
2216 langIt != langLst.end();
2217 ++langIt )
2218 {
2219 if ( !(*langIt).isEmpty() && !result.contains( *langIt ) )
2220 result += *langIt;
2221 }
2222 }
2223 d->langTwoAlpha = result;
2224 return result;
2225}
2226
2227QStringList KLocale::allLanguagesTwoAlpha() const
2228{
2229 if (!d->languages)
2230//US d->languages = new KConfig("all_languages", true, false, "locale");
2231 d->languages = new KConfig(locateLocal( "locale", "all_languages"));
2232
2233//US return d->languages->groupList();
2234 qDebug("KLocale::allLanguagesTwoAlpha has to be fixed.");
2235 return *(new QStringList());
2236
2237}
2238
2239QString KLocale::twoAlphaToLanguageName(const QString &code) const
2240{
2241 if (!d->languages)
2242//US d->languages = new KConfig("all_languages", true, false, "locale");
2243 d->languages = new KConfig(locateLocal( "locale", "all_languages"));
2244
2245 d->languages->setGroup(code.lower());
2246 return d->languages->readEntry("Name");
2247}
2248
2249QStringList KLocale::allCountriesTwoAlpha() const
2250{
2251 QStringList countries;
2252
2253 qDebug("KLocale::allCountriesTwoAlpha has to be fixed.");
2254//US QStringList paths = KGlobal::dirs()->findAllResources("locale", "l10n/*/entry.desktop");
2255 QStringList paths = KGlobal::dirs()->findAllResources("locale", "l10n/*/entry.desktop", true, true);
2256
2257 for(QStringList::ConstIterator it = paths.begin();
2258 it != paths.end(); ++it)
2259 {
2260 QString code = (*it).mid((*it).length()-16, 2);
2261 if (code != "/C")
2262 countries.append(code);
2263 }
2264 return countries;
2265}
2266
2267QString KLocale::twoAlphaToCountryName(const QString &code) const
2268{
2269//US KConfig cfg("l10n/"+code.lower()+"/entry.desktop", true, false, "locale");
2270 KConfig cfg(locateLocal("locale", "l10n/"+code.lower()+"/entry.desktop"));
2271 cfg.setGroup("KCM Locale");
2272 return cfg.readEntry("Name");
2273}
2274
2275void KLocale::setCalendar(const QString & calType)
2276{
2277 doFormatInit();
2278
2279 d->calendarType = calType;
2280
2281 delete d->calendar;
2282 d->calendar = 0;
2283}
2284
2285QString KLocale::calendarType() const
2286{
2287 doFormatInit();
2288
2289 return d->calendarType;
2290}
2291
2292const KCalendarSystem * KLocale::calendar() const
2293{
2294 doFormatInit();
2295
2296 // Check if it's the correct calendar?!?
2297//US we are always using the gregorian calendar
2298//US if ( !d->calendar )
2299//US d->calendar = KCalendarSystemFactory::create( d->calendarType, this );
2300 if ( !d->calendar )
2301 d->calendar = new KCalendarSystemGregorian;
2302
2303 return d->calendar;
2304}
2305
2306KLocale::KLocale(const KLocale & rhs)
2307{
2308 d = new KLocalePrivate;
2309
2310 *this = rhs;
2311}
2312
2313KLocale & KLocale::operator=(const KLocale & rhs)
2314{
2315 // Numbers and money
2316 m_decimalSymbol = rhs.m_decimalSymbol;
2317 m_thousandsSeparator = rhs.m_thousandsSeparator;
2318 m_currencySymbol = rhs.m_currencySymbol;
2319 m_monetaryDecimalSymbol = rhs.m_monetaryDecimalSymbol;
2320 m_monetaryThousandsSeparator = rhs.m_monetaryThousandsSeparator;
2321 m_positiveSign = rhs.m_positiveSign;
2322 m_negativeSign = rhs.m_negativeSign;
2323 m_fracDigits = rhs.m_fracDigits;
2324 m_positivePrefixCurrencySymbol = rhs.m_positivePrefixCurrencySymbol;
2325 m_negativePrefixCurrencySymbol = rhs.m_negativePrefixCurrencySymbol;
2326 m_positiveMonetarySignPosition = rhs.m_positiveMonetarySignPosition;
2327 m_negativeMonetarySignPosition = rhs.m_negativeMonetarySignPosition;
2328
2329 // Date and time
2330 m_timeFormat = rhs.m_timeFormat;
2331 m_dateFormat = rhs.m_dateFormat;
2332 m_dateFormatShort = rhs.m_dateFormatShort;
2333
2334 m_language = rhs.m_language;
2335 m_country = rhs.m_country;
2336
2337 // the assignment operator works here
2338 *d = *rhs.d;
2339 d->languages = 0; // Don't copy languages
2340 d->calendar = 0; // Don't copy the calendar
2341
2342 return *this;
2343}
2344
2345bool KLocale::setCharset(const QString & ) { return true; }
2346QString KLocale::charset() const { return QString::fromLatin1("UTF-8"); }
2347
2348
2349int KLocale::timezoneOffset( QString timeZone )
2350{
2351 int ret = 1001;
2352 int index = mTimeZoneList.findIndex( timeZone );
2353 if ( index < 24 )
2354 ret = ( index-11 ) * 60 ;
2355 return ret;
2356}
2357
2358QStringList KLocale::timeZoneList() const
2359{
2360 return mTimeZoneList;
2361}
2362void KLocale::setTimezone( const QString &timeZone )
2363{
2364 mTimeZoneOffset = timezoneOffset( timeZone );
2365}
2366
2367void KLocale::setDaylightSaving( bool b, int start , int end )
2368{
2369 daylightEnabled = b;
2370 daylightStart = start;
2371 daylightEnd = end;
2372 mSouthDaylight = (end < start);
2373 // qDebug("klocale daylight %d %d %d ", b, start , end );
2374}
2375
2376int KLocale::localTimeOffset( const QDateTime &dt )
2377{
2378 bool addDaylight = false;
2379 if ( daylightEnabled ) {
2380 int d_end, d_start;
2381 int dayofyear = dt.date().dayOfYear();
2382 int year = dt.date().year();
2383 int add = 0;
2384 if ( QDate::leapYear(year) )
2385 add = 1;
2386 QDate date ( year,1,1 );
2387 if ( daylightEnd > 59 )
2388 d_end = daylightEnd +add;
2389 else
2390 d_end = daylightEnd;
2391 if ( daylightStart > 59 )
2392 d_start = daylightStart +add;
2393 else
2394 d_start = daylightStart;
2395 QDate s_date = date.addDays( d_start -1 );
2396 QDate e_date = date.addDays( d_end -1 );
2397 int dof = s_date.dayOfWeek();
2398 if ( dof < 7 )
2399 s_date = s_date.addDays( -dof );
2400 dof = e_date.dayOfWeek();
2401 if ( dof < 7 )
2402 e_date = e_date.addDays( -dof );
2403 QTime startTime ( 3,0,0 );
2404 QDateTime startDt( s_date, startTime );
2405 QDateTime endDt( e_date, startTime );
2406 //qDebug("dayligt saving start %s end %s ",startDt.toString().latin1(),endDt.toString().latin1( ));
2407 if ( mSouthDaylight ) {
2408 if ( ! ( endDt < dt && dt < startDt) )
2409 addDaylight = true;
2410 } else {
2411 if ( startDt < dt && dt < endDt )
2412 addDaylight = true;
2413
2414
2415 }
2416 }
2417 int addMin = 0;
2418 if ( addDaylight )
2419 addMin = 60;
2420 return mTimeZoneOffset + addMin;
2421}
2422
2423void KLocale::setHore24Format ( bool b )
2424{
2425 mHourF24Format = b;
2426}
2427void KLocale::setWeekStartMonday( bool b )
2428{
2429 mWeekStartsMonday = b;
2430}
2431void KLocale::setIntDateFormat( int i )
2432{
2433 mIntDateFormat = i;
2434}
2435void KLocale::setLanguage( int i )
2436{
2437 mLanguage = i;
2438}
2439
2440
2441
diff --git a/microkde/kdecore/klocale_new.h b/microkde/kdecore/klocale_new.h
new file mode 100644
index 0000000..777c0bd
--- a/dev/null
+++ b/microkde/kdecore/klocale_new.h
@@ -0,0 +1,1224 @@
1#ifndef MINIKDE_KLOCALE_H
2#define MINIKDE_KLOCALE_H
3
4#include <qstring.h>
5#include <qstringlist.h>
6#include <qdict.h>
7
8class QStringList;
9class QTextCodec;
10class QDate;
11class QTime;
12class QDateTime;
13
14class KGlobal;
15class KConfig;
16class KConfigBase;
17class KLocalePrivate;
18class KCatalogue;
19class KCalendarSystem;
20
21#ifndef I18N_NOOP
22#define I18N_NOOP(x) (x)
23#endif
24
25void setLocaleDict( QDict<char> * dict );
26
27/**
28 * i18n is the function that does everything you need to translate
29 * a string. You just wrap around every user visible string a i18n
30 * call to get a QString with the string in the user's preferred
31 * language.
32 *
33 * The argument must be an UTF-8 encoded string (If you only use
34 * characters that are in US-ASCII, you're on the safe side. But
35 * for e.g. german umlauts or french accents should be recoded to
36 * UTF-8)
37 **/
38QString i18n(const char *text);
39
40/**
41 * If the string is too ambiguous to be translated well to a non-english
42 * language, use this form of i18n to separate lookup string and english
43 * text.
44 * @see translate
45 **/
46QString i18n(const char *index, const char *text);
47
48/**
49 * If you want to handle plural forms, use this form of i18n.
50 * The plural has to contain a %n where n fits into.
51 * @see translate
52 **/
53QString i18n(const char *singular, const char *plural, unsigned long n);
54
55/**
56 * Qt3's uic generates i18n( "msg", "comment" ) calls which conflict
57 * with our i18n method. We use uic -tr tr2i18n to redirect
58 * to the right i18n() function
59**/
60inline QString tr2i18n(const char* message, const char* =0) {
61 return i18n(message);
62}
63
64/**
65 *
66 * KLocale provides support for country specific stuff like
67 * the national language.
68 *
69 * KLocale supports translating, as well as specifying the format
70 * for numbers, currency, time, and date.
71 *
72 * @author Stephan Kulow <coolo@kde.org>, Preston Brown <pbrown@kde.org>,
73 * Hans Petter Bieker <bieker@kde.org>, Lukas Tinkl <lukas.tinkl@suse.cz>
74 * @short class for supporting locale settings and national language
75 */
76class KLocale
77{
78 friend class KGlobal; // for initInstance()
79public:
80 /**
81 * Constructs a KLocale with the given catalogue name.
82 * The constructor looks for an entry Locale/Language in the
83 * configuration file.
84 * If no config file is specified, it will also look for languages
85 * using the environment variables (KDE_LANG, LC_MESSAGES, LC_ALL, LANG),
86 * as well as the global configuration fie. If we were not able to use
87 * non of the specified languages, the default language (en_US) will be
88 * used.
89 *
90 * If you specify a configuration file, it has to be valid until
91 * the KLocale object is destroyed.
92 *
93 * @param catalogue The name of the main language file
94 * @param config The configuration file to use.
95 */
96 KLocale( const QString& catalogue, KConfig *config = 0 );
97
98 /**
99 * Copy constructor.
100 */
101 KLocale( const KLocale & rhs );
102
103 /**
104 * Assignment operator.
105 */
106 KLocale& operator= ( const KLocale & rhs );
107
108 /**
109 * Destructor.
110 */
111 ~KLocale();
112
113 /**
114 * Translates the string into the corresponding string in
115 * the national language, if available. If not, returns
116 * the string itself.
117 * There is a KDE wide message file that contains the most
118 * often used phrases, so we can avoid duplicating the
119 * translation of these phrases. If a phrase is not found
120 * in the catalogue given to the constructor, it will search
121 * in the system catalog. This makes it possible to override
122 * some phrases for your needs.
123 *
124 * The argument must be an UTF-8 encoded string (If you only use
125 * characters that are in US-ASCII you're on the safe side. But
126 * for e.g. german umlauts or french accents should be recoded to
127 * UTF-8)
128 *
129 * @param index The lookup text and default text, if not found.
130 */
131 QString translate( const char *index ) const;
132
133 /**
134 * Translates the string into the corresponding string in the
135 * national language, if available.
136 *
137 * The real contents of the string is in the argument fallback,
138 * but the meaning of it is coded into the argument index.
139 * In some cases you'll need this function, when english is
140 * too ambiguous to express it.
141 *
142 * Most of the times the translators will tell you if it can't
143 * be translated as it, but think of cases as "New", where the
144 * translations differs depending on what is New.
145 * Or simple cases as "Open", that can be used to express something
146 * is open or it can be used to express that you want something to
147 * open... There are tons of such examples.
148 *
149 * If translate("Open") is not enough to translate it well, use
150 * translate("To Open", "Open") or translate("Is Open", "Open").
151 * The english user will see "Open" in both cases, but the translated
152 * version may vary. Of course you can also use i18n()
153 *
154 * @param index The lookup text
155 * @param fallback the default text, if not found
156 * @return translation
157 */
158 QString translate( const char *index, const char *fallback) const;
159
160 /**
161 * Used to get the correct, translated singular or plural of a
162 * word.
163 * @param singular the singular form of the word, for example "file".
164 * @param plural the plural form of the word. Must contain a "%n" that will
165 * be replaced by the number @n, for example "%n files"
166 * @param n the number
167 * @return the correct singular or plural for the selected language,
168 * depending on n
169 */
170 QString translate( const char *singular, const char *plural,
171 unsigned long n) const;
172
173 /**
174 * Changes the current encoding.
175 *
176 * @param mibEnum The mib of the preferred codec
177 *
178 * @return True on success.
179 */
180 bool setEncoding(int mibEnum);
181
182 /**
183 * Changes the current language. The current language will be left
184 * unchanged if failed. It will force a reload of the country specific
185 * configuration as well.
186 *
187 * @param language The language code.
188 *
189 * @return True on success.
190 */
191 bool setLanguage(const QString & language);
192
193 /**
194 * Changes the list of prefed languages for the locale. The first valid
195 * language in the list will be used, or the default (en_US) language
196 * will be used if non of the specified languages were available.
197 *
198 * @param languages The list of language codes.
199 *
200 * @return True if one of the specified languages were used.
201 */
202 bool setLanguage(const QStringList & languages);
203
204 /**
205 * Changes the current country. The current country will be left
206 * unchanged if failed. It will force a reload of the country specific
207 * configuration.
208 *
209 * @param country The ISO 3166 country code.
210 *
211 * @return True on success.
212 */
213 bool setCountry(const QString & country);
214
215 /**
216 * Various positions for where to place the positive or negative
217 * sign when they are related to a monetary value.
218 */
219 enum SignPosition { ParensAround = 0, BeforeQuantityMoney = 1,
220 AfterQuantityMoney = 2,
221 BeforeMoney = 3, AfterMoney = 4 };
222
223 /**
224 * Returns what a decimal point should look like ("." or "," etc.)
225 * according to the current locale or user settings.
226 *
227 * @return The decimal symbol used by locale.
228 */
229 QString decimalSymbol() const;
230
231 /**
232 * Returns what the thousands separator should look
233 * like ("," or "." etc.)
234 * according to the current locale or user settings.
235 *
236 * @return The thousands separator used by locale.
237 */
238 QString thousandsSeparator() const;
239
240 /**
241 * Returns what the symbol denoting currency in the current locale
242 * as as defined by user settings should look like.
243 *
244 * @return The default currency symbol used by locale.
245 */
246 QString currencySymbol() const;
247
248 /**
249 * Returns what a decimal point should look like ("." or "," etc.)
250 * for monetary values, according to the current locale or user
251 * settings.
252 *
253 * @return The monetary decimal symbol used by locale.
254 */
255 QString monetaryDecimalSymbol() const;
256
257 /**
258 * Returns what a thousands separator for monetary values should
259 * look like ("," or " " etc.) according to the current locale or
260 * user settings.
261 *
262 * @return The monetary thousands separator used by locale.
263 */
264 QString monetaryThousandsSeparator() const;
265
266 /**
267 * Returns what a positive sign should look like ("+", " ", etc.)
268 * according to the current locale or user settings.
269 *
270 * @return The positive sign used by locale.
271 */
272 QString positiveSign() const;
273
274 /**
275 * Returns what a negative sign should look like ("-", etc.)
276 * according to the current locale or user settings.
277 *
278 * @return The negative sign used by locale.
279 */
280 QString negativeSign() const;
281
282 /**
283 * The number of fractional digits to include in numeric/monetary
284 * values (usually 2).
285 *
286 * @return Default number of fractional digits used by locale.
287 */
288 int fracDigits() const;
289
290 /**
291 * If and only if the currency symbol precedes a positive value,
292 * this will be true.
293 *
294 * @return Where to print the currency symbol for positive numbers.
295 */
296 bool positivePrefixCurrencySymbol() const;
297
298 /**
299 * If and only if the currency symbol precedes a negative value,
300 * this will be true.
301 *
302 * @return True if the currency symbol precedes negative numbers.
303 */
304 bool negativePrefixCurrencySymbol() const;
305
306 /**
307 * Returns the position of a positive sign in relation to a
308 * monetary value.
309 *
310 * @return Where/how to print the positive sign.
311 * @see SignPosition
312 */
313 SignPosition positiveMonetarySignPosition() const;
314
315 /**
316 * Denotes where to place a negative sign in relation to a
317 * monetary value.
318 *
319 * @return Where/how to print the negative sign.
320 * @see SignPosition
321 */
322 SignPosition negativeMonetarySignPosition() const;
323
324 /**
325 * Given a double, converts that to a numeric string containing
326 * the localized monetary equivalent.
327 *
328 * e.g. given 123456, return "$ 123,456.00".
329 *
330 * @param num The number we want to format
331 * @param currency The currency symbol you want.
332 * @param digits Number of fractional digits, or -1 for the default
333 * value
334 *
335 * @return The number of money as a localized string
336 * @see fracDigits()
337 */
338 QString formatMoney(double num,
339 const QString & currency = QString::null,
340 int digits = -1) const;
341
342 /**
343 * Given a double, converts that to a numeric string containing
344 * the localized numeric equivalent.
345 *
346 * e.g. given 123456.78F, return "123,456.78" (for some European country).
347 * If precision isn't specified, 2 is used.
348 *
349 * @param num The number to convert
350 * @param precision Number of fractional digits used.
351 *
352 * @return The number as a localized string
353 */
354 QString formatNumber(double num, int precision = -1) const;
355
356 /**
357 * Given an integer, converts that to a numeric string containing
358 * the localized numeric equivalent.
359 *
360 * e.g. given 123456L, return "123,456" (for some European country).
361 *
362 * @param num The number to convert
363 *
364 * @return The number as a localized string
365 * @since 3.2
366 */
367 QString formatLong(long num) const;
368
369 /**
370 * Use this to determine whether nouns are declined in
371 * locale's language. This property should remain
372 * read-only (no setter function)
373 *
374 * @return If nouns are declined
375 * @since 3.1
376 */
377 bool nounDeclension() const;
378
379 /**
380 * Returns a string formatted to the current locale's conventions
381 * regarding dates.
382 *
383 * @param pDate The date to be formated.
384 * @param shortFormat True for non text dates.
385 *
386 * @return The date as a string
387 */
388 QString formatDate(const QDate &pDate, bool shortFormat = false) const;
389
390 /**
391 * Use this to determine whether in dates a possessive form of month
392 * name is preferred ("of January" rather than "January")
393 *
394 * @return If possessive form should be used
395 * @since 3.1
396 */
397 bool dateMonthNamePossessive() const;
398
399 /**
400 * Returns a string formatted to the current locale's conventions
401 * regarding times.
402 *
403 * @param pTime The time to be formated.
404 * @param includeSecs if true, seconds are included in the output,
405 * otherwise only hours and minutes are formatted.
406 *
407 * @return The time as a string
408 */
409 QString formatTime(const QTime &pTime, bool includeSecs = false) const;
410
411 /**
412 * Use this to determine if the user wants a 12 hour clock.
413 *
414 * @return If the user wants 12h clock
415 */
416 bool use12Clock() const;
417
418 /**
419 * @deprecated
420 *
421 * Please use the @ref weekStartDay method instead.
422 *
423 * Use this to determine if the user wants the week to start on Monday.
424 *
425 * @return true if the week starts on Monday
426 */
427 bool weekStartsMonday() const; //### remove for KDE 4.0
428
429 /**
430 * Use this to determine which day is the first day of the week.
431 *
432 * @return an integer (Monday=1..Sunday=7)
433 * @since 3.1
434 */
435 int weekStartDay() const;
436
437 /**
438 * @deprecated
439 *
440 * Returns a string containing the name of the month name used in the Gregorian calendar.
441 *
442 * @param i the month number of the year starting at 1/January.
443 * @param shortName we will return the short version of the string.
444 *
445 * @return The name of the month
446 */
447 QString monthName(int i, bool shortName = false) const;
448
449 /**
450 * @deprecated
451 *
452 * Returns a string containing the possessive form of the month name used in the Gregorian calendar.
453 * ("of January", "of February", etc.)
454 * It's needed in long format dates in some languages.
455 *
456 * @param i the month number of the year starting at 1/January.
457 * @param shortName we will return the short version of the string.
458 *
459 * @return The possessive form of the name of the month
460 * @since 3.1
461 */
462 QString monthNamePossessive(int i, bool shortName = false) const;
463
464 /**
465 * @deprecated
466 *
467 * Returns a string containing the name of the week day used in the Gregorian calendar.
468 *
469 * @param i the day number of the week starting at 1/Monday.
470 * @param shortName we will return the short version of the string.
471 *
472 * @return The name of the day
473 */
474 QString weekDayName(int i, bool shortName = false) const;
475
476 /**
477 * Returns a pointer to the calendar system object.
478 *
479 * @return the current calendar system instance
480 * @since 3.2
481 */
482 const KCalendarSystem * calendar() const;
483
484 /**
485 * Returns the name of the calendar system that is currently being
486 * used by the system.
487 *
488 * @return the name of the calendar system
489 * @since 3.2
490 */
491 QString calendarType() const;
492
493 /**
494 * Changes the current calendar system to the calendar specified.
495 * Currently is "gregorian" and "hijri" supported. If the calendar
496 * system specified is not found, gregorian will be used.
497 *
498 * @param calendarType the name of the calendar type
499 * @since 3.2
500 */
501 void setCalendar(const QString & calendarType);
502
503 /**
504 * Returns a string formated to the current locale's conventions
505 * regarding both date and time.
506 *
507 * @param pDateTime The date and time to be formated.
508 * @param shortFormat using the short date format.
509 * @param includeSecs using the short date format.
510 *
511 * @return The date and time as a string
512 */
513 QString formatDateTime(const QDateTime &pDateTime,
514 bool shortFormat = true,
515 bool includeSecs = false) const;
516
517 /**
518 * Converts a localized monetary string to a double.
519 *
520 * @param numStr the string we want to convert.
521 * @param ok the boolean that is set to false if it's not a number.
522 * If @p ok is 0, it will be ignored
523 *
524 * @return The string converted to a double
525 */
526 double readMoney(const QString &numStr, bool * ok = 0) const;
527
528 /**
529 * Converts a localized numeric string to a double.
530 *
531 * @param numStr the string we want to convert.
532 * @param ok the boolean that is set to false if it's not a number.
533 * If @p ok is 0, it will be ignored
534 *
535 * @return The string converted to a double
536 */
537 double readNumber(const QString &numStr, bool * ok = 0) const;
538
539 /**
540 * Converts a localized date string to a QDate.
541 * The bool pointed by ok will be invalid if the date entered was not valid.
542 *
543 * @param str the string we want to convert.
544 * @param ok the boolean that is set to false if it's not a valid date.
545 * If @p ok is 0, it will be ignored
546 *
547 * @return The string converted to a QDate
548 */
549 QDate readDate(const QString &str, bool* ok = 0) const;
550
551 /**
552 * Converts a localized date string to a QDate, using the specified format.
553 * You will usually not want to use this method.
554 */
555 QDate readDate( const QString &intstr, const QString &fmt, bool* ok = 0) const;
556
557 enum ReadDateFlags {
558 NormalFormat = 1,
559 ShortFormat = 2
560 };
561
562 /**
563 * Converts a localized date string to a QDate.
564 * This method is stricter than readDate(str,&ok): it will either accept
565 * a date in full format or a date in short format, depending on @p flags.
566 *
567 * @param str the string we want to convert.
568 * @param flags whether the date string is to be in full format or in short format.
569 * @param ok the boolean that is set to false if it's not a valid date.
570 * If @p ok is 0, it will be ignored
571 *
572 * @return The string converted to a QDate
573 * @since 3.2
574 */
575 QDate readDate(const QString &str, ReadDateFlags flags, bool *ok = 0) const;
576
577 /**
578 * Converts a localized time string to a QTime.
579 * This method will try to parse it with seconds, then without seconds.
580 * The bool pointed by ok will be false if the time entered was not valid.
581 *
582 * @param str the string we want to convert.
583 * @param ok the boolean that is set to false if it's not a valid time.
584 * If @p ok is 0, it will be ignored
585 *
586 * @return The string converted to a QTime
587 */
588 QTime readTime(const QString &str, bool* ok = 0) const;
589
590 enum ReadTimeFlags {
591 WithSeconds = 0, // default (no flag set)
592 WithoutSeconds = 1
593 }; // (maybe use this enum as a bitfield, if adding independent features?)
594 /**
595 * Converts a localized time string to a QTime.
596 * This method is stricter than readTime(str,&ok): it will either accept
597 * a time with seconds or a time without seconds.
598 * Use this method when the format is known by the application.
599 *
600 * @param str the string we want to convert.
601 * @param flags whether the time string is expected to contain seconds or not.
602 * @param ok the boolean that is set to false if it's not a valid time.
603 * If @p ok is 0, it will be ignored
604 *
605 * @return The string converted to a QTime
606 * @since 3.2
607 */
608 QTime readTime(const QString &str, ReadTimeFlags flags, bool *ok = 0) const;
609
610 /**
611 * Returns the language used by this object. The domain AND the
612 * library translation must be available in this language.
613 * @ref defaultLanguage() is returned by default, if no other available.
614 *
615 * @return The currently used language.
616 */
617 QString language() const;
618
619 /**
620 * Returns the country code of the country where the user lives.
621 * @ref defaultCountry() is returned by default, if no other available.
622 *
623 * @return The country code for the user.
624 */
625 QString country() const;
626
627 /**
628 * Returns the preferred languages as ISO 639-1 codes. This means
629 * that information about country is removed. If the internal language
630 * code might be represented by more than one 639-1 code, they will all be
631 * listed (but only once).
632 *
633 * If the selected languages are "nn, nb, pt_BR", you will get:
634 * "nn, no, nb, pt".
635 *
636 * @return List of language codes
637 *
638 * @see languageList
639 */
640 QStringList languagesTwoAlpha() const;
641
642 /**
643 * Returns the languages selected by user. The codes returned here is the
644 * internal language codes.
645 *
646 * @return List of language codes
647 *
648 * @see languagesTwoAlpha
649 */
650 QStringList languageList() const;
651
652 /**
653 * Returns the user's preferred encoding.
654 *
655 * @return The name of the preferred encoding
656 *
657 * @see codecForEncoding
658 * @see encodingMib
659 */
660 const char * encoding() const;
661
662 /**
663 * Returns the user's preferred encoding.
664 *
665 * @return The Mib of the preferred encoding
666 *
667 * @see encoding
668 * @see codecForEncoding
669 */
670 int encodingMib() const;
671 /**
672 * Returns the user's preferred encoding. Should never be NULL.
673 *
674 * @return The codec for the preferred encoding
675 *
676 * @see encoding
677 * @see encodingMib
678 */
679 QTextCodec * codecForEncoding() const;
680
681 /**
682 * Returns the file encoding.
683 *
684 * @return The Mib of the file encoding
685 *
686 * @see QFile::encodeName
687 * @see QFile::decodeName
688 */
689 int fileEncodingMib() const;
690
691 /**
692 * Changes the current date format.
693 *
694 * The format of the date is a string which contains variables that will
695 * be replaced:
696 * @li %Y with the century (e.g. "19" for "1984")
697 * @li %y with the lower 2 digits of the year (e.g. "84" for "1984")
698 * @li %n with the month (January="1", December="12")
699 * @li %m with the month with two digits (January="01", December="12")
700 * @li %e with the day of the month (e.g. "1" on the first of march)
701 * @li %d with the day of the month with two digits(e.g. "01" on the first of march)
702 * @li %b with the short form of the month (e.g. "Jan" for January)
703 * @li %a with the short form of the weekday (e.g. "Wed" for Wednesday)
704 * @li %A with the long form of the weekday (e.g. "Wednesday" for Wednesday)
705 * Everything else in the format string will be taken as is.
706 * For example, March 20th 1989 with the format "%y:%m:%d" results
707 * in "89:03:20".
708 *
709 * @param format The new date format
710 */
711 void setDateFormat(const QString & format);
712 /**
713 * Changes the current short date format.
714 *
715 * The format of the date is a string which contains variables that will
716 * be replaced:
717 * @li %Y with the century (e.g. "19" for "1984")
718 * @li %y with the lower 2 digits of the year (e.g. "84" for "1984")
719 * @li %n with the month (January="1", December="12")
720 * @li %m with the month with two digits (January="01", December="12")
721 * @li %e with the day of the month (e.g. "1" on the first of march)
722 * @li %d with the day of the month with two digits(e.g. "01" on the first of march)
723 * @li %b with the short form of the month (e.g. "Jan" for January)
724 * @li %a with the short form of the weekday (e.g. "Wed" for Wednesday)
725 * @li %A with the long form of the weekday (e.g. "Wednesday" for Wednesday)
726 * Everything else in the format string will be taken as is.
727 * For example, March 20th 1989 with the format "%y:%m:%d" results
728 * in "89:03:20".
729 *
730 * @param format The new short date format
731 */
732 void setDateFormatShort(const QString & format);
733 /**
734 * Changes the form of month name used in dates.
735 *
736 * @param possessive True if possessive forms should be used
737 * @since 3.1
738 */
739 void setDateMonthNamePossessive(bool possessive);
740 /**
741 * Changes the current time format.
742 *
743 * The format of the time is string a which contains variables that will
744 * be replaced:
745 * @li %H with the hour in 24h format and 2 digits (e.g. 5pm is "17", 5am is "05")
746 * @li %k with the hour in 24h format and one digits (e.g. 5pm is "17", 5am is "5")
747 * @li %I with the hour in 12h format and 2 digits (e.g. 5pm is "05", 5am is "05")
748 * @li %l with the hour in 12h format and one digits (e.g. 5pm is "5", 5am is "5")
749 * @li %M with the minute with 2 digits (e.g. the minute of 07:02:09 is "02")
750 * @li %S with the seconds with 2 digits (e.g. the minute of 07:02:09 is "09")
751 * @li %p with pm or am (e.g. 17.00 is "pm", 05.00 is "am")
752 * Everything else in the format string will be taken as is.
753 * For example, 5.23pm with the format "%H:%M" results
754 * in "17:23".
755 *
756 * @param format The new time format
757 */
758 void setTimeFormat(const QString & format);
759
760 /**
761 * @deprecated
762 *
763 * Please use @ref setWeekStartDay instead.
764 *
765 * Changes how KLocale defines the first day in week.
766 *
767 * @param start True if Monday is the first day in the week
768 */
769 void setWeekStartsMonday(bool start); //### remove for KDE 4.0
770
771 /**
772 * Changes how KLocale defines the first day in week.
773 *
774 * @param day first day of the week (Monday=1..Sunday=7) as integer
775 * @since 3.1
776 */
777 void setWeekStartDay(int day);
778 /**
779 * Returns the currently selected date format.
780 *
781 * @return Current date format.
782 * @see setDateFormat()
783 */
784 QString dateFormat() const;
785 /**
786 * Returns the currently selected short date format.
787 *
788 * @return Current short date format.
789 * @see setDateFormatShort()
790 */
791 QString dateFormatShort() const;
792 /**
793 * Returns the currently selected time format.
794 *
795 * @return Current time format.
796 * @see setTimeFormat()
797 */
798 QString timeFormat() const;
799
800 /**
801 * Changes the symbol used to identify the decimal pointer.
802 *
803 * @param symbol The new decimal symbol.
804 */
805 void setDecimalSymbol(const QString & symbol);
806 /**
807 * Changes the separator used to group digits when formating numbers.
808 *
809 * @param separator The new thousands separator.
810 */
811 void setThousandsSeparator(const QString & separator);
812 /**
813 * Changes the sign used to identify a positive number. Normally this is
814 * left blank.
815 *
816 * @param sign Sign used for positive numbers.
817 */
818 void setPositiveSign(const QString & sign);
819 /**
820 * Changes the sign used to identify a negative number.
821 *
822 * @param sign Sign used for negative numbers.
823 */
824 void setNegativeSign(const QString & sign);
825 /**
826 * Changes the sign position used for positive monetary values.
827 *
828 * @param signpos The new sign position
829 */
830 void setPositiveMonetarySignPosition(SignPosition signpos);
831 /**
832 * Changes the sign position used for negative monetary values.
833 *
834 * @param signpos The new sign position
835 */
836 void setNegativeMonetarySignPosition(SignPosition signpos);
837 /**
838 * Changes the position where the currency symbol should be printed for
839 * positive monetary values.
840 *
841 * @param prefix True if the currency symbol should be prefixed instead of
842 * postfixed
843 */
844 void setPositivePrefixCurrencySymbol(bool prefix);
845 /**
846 * Changes the position where the currency symbol should be printed for
847 * negative monetary values.
848 *
849 * @param prefix True if the currency symbol should be prefixed instead of
850 * postfixed
851 */
852 void setNegativePrefixCurrencySymbol(bool prefix);
853 /**
854 * Changes the number of digits used when formating numbers.
855 *
856 * @param digits The default number of digits to use.
857 */
858 void setFracDigits(int digits);
859 /**
860 * Changes the separator used to group digits when formating monetary values.
861 *
862 * @param separator The new thousands separator.
863 */
864 void setMonetaryThousandsSeparator(const QString & separator);
865 /**
866 * Changes the symbol used to identify the decimal pointer for monetary
867 * values.
868 *
869 * @param symbol The new decimal symbol.
870 */
871 void setMonetaryDecimalSymbol(const QString & symbol);
872 /**
873 * Changes the current currency symbol.
874 *
875 * @param symbol The new currency symbol
876 */
877 void setCurrencySymbol(const QString & symbol);
878
879 /**
880 * Returns the preferred page size for printing.
881 *
882 * @return The preferred page size, cast it to QPrinter::PageSize
883 */
884 int pageSize() const;
885
886 /**
887 * Changes the preferred page size when printing.
888 *
889 * @param paperFormat the new preferred page size in the format QPrinter::PageSize
890 */
891 void setPageSize(int paperFormat);
892
893 /**
894 * The Metric system will give you information in mm, while the
895 * Imperial system will give you information in inches.
896 */
897 enum MeasureSystem { Metric, Imperial };
898
899 /**
900 * Returns which measuring system we use.
901 *
902 * @return The preferred measuring system
903 */
904 MeasureSystem measureSystem() const;
905
906 /**
907 * Changes the preferred measuring system.
908 *
909 * @return value The preferred measuring system
910 */
911 void setMeasureSystem(MeasureSystem value);
912
913 /**
914 * Adds another catalogue to search for translation lookup.
915 * This function is useful for extern libraries and/or code,
916 * that provides its own messages.
917 *
918 * If the catalogue does not exist for the chosen language,
919 * it will be ignored and en_US will be used.
920 *
921 * @param catalogue The catalogue to add.
922 */
923 void insertCatalogue(const QString& catalogue);
924
925 /**
926 * Removes a catalog for translation lookup.
927 * @param catalogue The catalogue to remove.
928 * @see insertCatalogue()
929 */
930 void removeCatalogue(const QString &catalogue);
931
932 /**
933 * Sets the active catalog for translation lookup.
934 * @param catalogue The catalogue to activate.
935 */
936 void setActiveCatalogue(const QString &catalogue);
937
938 /**
939 * Translates a message as a QTranslator is supposed to.
940 * The parameters are similar to i18n(), but the result
941 * value has other semantics (it can be QString::null)
942 * @since 3.1
943 **/
944 QString translateQt(const char *context,
945 const char *sourceText,
946 const char *message) const;
947
948 /**
949 * Returns list of all known ISO 639-1 codes.
950 * @return a list of all language codes
951 * @since 3.1
952 */
953 QStringList allLanguagesTwoAlpha() const;
954
955 /**
956 * Convert a ISO 639-1 code to a human readable form.
957 * @param code the language ISO 639-1 code
958 * @return the human readable form
959 * @since 3.1
960 */
961 QString twoAlphaToLanguageName(const QString &code) const;
962
963 /**
964 * Returns list of all known country codes.
965 * @return a list of all country codes
966 * @since 3.1
967 */
968 QStringList allCountriesTwoAlpha() const;
969
970 /**
971 * Convert a country code to a human readable form.
972 * @param code the country code
973 * @return the human readable form of the country name
974 * @since 3.1
975 */
976 QString twoAlphaToCountryName(const QString &code) const;
977
978
979
980 int timezoneOffset( QString );
981 QStringList timeZoneList() const;
982 void setDaylightSaving( bool, int , int );
983 int localTimeOffset(const QDateTime &);
984 void setTimezone( const QString &timeZone );
985
986 void setHore24Format ( bool );
987 void setWeekStartMonday( bool );
988 void setIntDateFormat( int );
989 void setLanguage( int );
990
991
992
993 /**
994 * Returns the parts of the parameter str understood as language setting
995 * the format is language_COUNTRY.charset
996 *
997 * @param str The string to split.
998 * @param language This will be set to the language part of the string.
999 * @param country This will be set to the country part of the string.
1000 * @param charset This will be set to the charset part of the string.
1001 */
1002 static void splitLocale(const QString & str,
1003 QString & language,
1004 QString & country,
1005 QString & charset);
1006
1007 /**
1008 * Use this to as main catalogue for *all* KLocales, if not the appname
1009 * will be used. This function is best to be the very first instruction
1010 * in your program's main function as it only has an effect before the
1011 * first KLocale object is created (and this is in common KDE applications
1012 * quite early).
1013 *
1014 * @param catalogue Catalogue to override all other main catalogues.
1015 */
1016 static void setMainCatalogue(const char *catalogue);
1017
1018 /**
1019 * Finds localized resource in resourceDir( rtype ) + \<lang> + fname.
1020 *
1021 * @param fname relative path to find
1022 * @param rtype resource type to use
1023 */
1024 static QString langLookup(const QString &fname, const char *rtype = "html");
1025
1026 /**
1027 * Returns the name of the internal language.
1028 *
1029 * @return Name of the default language
1030 */
1031 static QString defaultLanguage();
1032
1033 /**
1034 * Returns the name of the default country.
1035 *
1036 * @return Name of the default country
1037 */
1038 static QString defaultCountry();
1039
1040
1041 /**
1042 * @internal Called from KConfigBackend to initialize language.
1043 */
1044 static QString _initLanguage(KConfigBase *config);
1045
1046#ifdef KDE_NO_COMPAT
1047private:
1048#endif
1049 /**
1050 * @deprecated
1051 * use formatMoney(double)
1052 */
1053 QString formatMoney(const QString &numStr) const;
1054
1055 /**
1056 * @deprecated
1057 * use formatNumber(double)
1058 */
1059 QString formatNumber(const QString &numStr) const;
1060
1061 /**
1062 * @deprecated
1063 * Use languageList()
1064 *
1065 * @return String containing language codes separated by colons
1066 */
1067 QString languages() const;
1068
1069 /**
1070 * @deprecated
1071 * @return True
1072 */
1073 bool setCharset(const QString & charset);
1074
1075 /**
1076 * @deprecated
1077 * @see encoding
1078 */
1079 QString charset() const;
1080
1081protected:
1082 /**
1083 * @internal Creates a KLocale object for KGlobal and inits the locale
1084 * pointer.
1085 */
1086 static void initInstance();
1087
1088private:
1089 /**
1090 * @internal Inits the localization part of the instance with the config
1091 * object.
1092 *
1093 * @param config The configuration object used for init.
1094 */
1095 void initFormat(KConfig *config);
1096
1097 /**
1098 * @internal Inits the language part of the instance with the given config
1099 * object. It should be valid and contain the global entries.
1100 *
1101 * @param config The configuration object used for init
1102 * @param useEnv True if we should use environment variables
1103 */
1104 void initLanguage(KConfig * config, bool useEnv);
1105
1106 /**
1107 * @internal Figures out which encoding the user prefers.
1108 *
1109 * @param config The configuration object used for init
1110 */
1111 void initEncoding(KConfig * config);
1112
1113 /**
1114 * @internal Figures out which catalogues to use.
1115 *
1116 * @param catalogue The name of the main catalogue
1117 */
1118 void initCatalogue(const QString & catalogue);
1119
1120 /**
1121 * @internal Figures out which encoding the user prefers for filenames
1122 * and sets up the appropriate QFile encoding and decoding functions.
1123 */
1124 void initFileNameEncoding(KConfig *config);
1125
1126 /**
1127 * @internal A QFile filename encoding function (QFile::encodeFn).
1128 */
1129 static QCString encodeFileNameUTF8( const QString & fileName );
1130
1131 /**
1132 * @internal QFile filename decoding function (QFile::decodeFn).
1133 */
1134 static QString decodeFileNameUTF8( const QCString & localFileName );
1135
1136 /**
1137 * @internal Changes the file name of the catalogue to the correct
1138 * one.
1139 */
1140 void initCatalogue( KCatalogue & catalogue );
1141
1142 /**
1143 * @internal Reads the language and format configuration form disk.
1144 */
1145 void doBindInit();
1146
1147 /**
1148 * @internal Ensures that the format configuration is read.
1149 */
1150 void doFormatInit() const;
1151
1152 /**
1153 * @internal Reads the format configuration from disk.
1154 */
1155 void initFormat();
1156
1157 /**
1158 * @internal function used by the two translate versions
1159 */
1160 QString translate_priv(const char *index,
1161 const char *text,
1162 const char ** original = 0) const;
1163
1164 /**
1165 * @internal function used to determine if we are using the en_US translation
1166 */
1167 bool useDefaultLanguage() const;
1168
1169 /**
1170 * @internal Checks if the specified language is installed
1171 */
1172 bool isLanguageInstalled(const QString & language) const;
1173
1174 /**
1175 * @internal Retrieves the file name of the catalogue, or QString::null
1176 * if not found.
1177 */
1178 static QString catalogueFileName(const QString & language,
1179 const KCatalogue & catalogue);
1180
1181
1182private:
1183 // Numbers and money
1184 QString m_decimalSymbol;
1185 QString m_thousandsSeparator;
1186 QString m_currencySymbol;
1187 QString m_monetaryDecimalSymbol;
1188 QString m_monetaryThousandsSeparator;
1189 QString m_positiveSign;
1190 QString m_negativeSign;
1191 int m_fracDigits;
1192 SignPosition m_positiveMonetarySignPosition;
1193 SignPosition m_negativeMonetarySignPosition;
1194
1195 // Date and time
1196 QString m_timeFormat;
1197 QString m_dateFormat;
1198 QString m_dateFormatShort;
1199
1200 QString m_language;
1201 QString m_country;
1202
1203 QStringList mTimeZoneList;
1204 bool daylightEnabled;
1205 int mDaylightTZoffset;
1206 int mNondaylightTZoffset;
1207 bool mSouthDaylight;
1208 int daylightStart, daylightEnd, mTimeZoneOffset;
1209 bool mWeekStartsMonday;
1210 bool mHourF24Format;
1211 int mIntDateFormat;
1212 int mLanguage;
1213
1214
1215
1216
1217 bool m_weekStartsMonday; //### remove for KDE 4.0
1218 bool m_positivePrefixCurrencySymbol;
1219 bool m_negativePrefixCurrencySymbol;
1220
1221 KLocalePrivate *d;
1222};
1223
1224#endif
diff --git a/microkde/kdecore/kmdcodec.cpp b/microkde/kdecore/kmdcodec.cpp
new file mode 100644
index 0000000..bc03569
--- a/dev/null
+++ b/microkde/kdecore/kmdcodec.cpp
@@ -0,0 +1,1127 @@
1/*
2 Copyright (C) 2000-2001 Dawit Alemayehu <adawit@kde.org>
3 Copyright (C) 2001 Rik Hemsley (rikkus) <rik@kde.org>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License (LGPL)
7 version 2 as published by the Free Software Foundation.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public
15 License along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18 RFC 1321 "MD5 Message-Digest Algorithm" Copyright (C) 1991-1992.
19 RSA Data Security, Inc. Created 1991. All rights reserved.
20
21 The KMD5 class is based on a C++ implementation of
22 "RSA Data Security, Inc. MD5 Message-Digest Algorithm" by
23 Mordechai T. Abzug,Copyright (c) 1995. This implementation
24 passes the test-suite as defined in RFC 1321.
25
26 The encoding and decoding utilities in KCodecs with the exception of
27 quoted-printable are based on the java implementation in HTTPClient
28 package by Ronald Tschal� Copyright (C) 1996-1999.
29
30 The quoted-printable codec as described in RFC 2045, section 6.7. is by
31 Rik Hemsley (C) 2001.
32*/
33
34//US #include <config.h>
35
36#include <stdio.h>
37#include <string.h>
38#include <stdlib.h>
39
40#include <kdebug.h>
41#include "kmdcodec.h"
42
43#define KMD5_S11 7
44#define KMD5_S12 12
45#define KMD5_S13 17
46#define KMD5_S14 22
47#define KMD5_S21 5
48#define KMD5_S22 9
49#define KMD5_S23 14
50#define KMD5_S24 20
51#define KMD5_S31 4
52#define KMD5_S32 11
53#define KMD5_S33 16
54#define KMD5_S34 23
55#define KMD5_S41 6
56#define KMD5_S42 10
57#define KMD5_S43 15
58#define KMD5_S44 21
59
60const char KCodecs::Base64EncMap[64] =
61{
62 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
63 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50,
64 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
65 0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
66 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E,
67 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,
68 0x77, 0x78, 0x79, 0x7A, 0x30, 0x31, 0x32, 0x33,
69 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2B, 0x2F
70};
71
72const char KCodecs::Base64DecMap[128] =
73{
74 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
75 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
76 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
77 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
78 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
79 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x3F,
80 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B,
81 0x3C, 0x3D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
82 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
83 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
84 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
85 0x17, 0x18, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00,
86 0x00, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20,
87 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
88 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,
89 0x31, 0x32, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00
90};
91
92const char KCodecs::UUEncMap[64] =
93{
94 0x60, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
95 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
96 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
97 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
98 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
99 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
100 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
101 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F
102};
103
104const char KCodecs::UUDecMap[128] =
105{
106 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
107 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
108 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
109 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
110 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
111 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
112 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
113 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
114 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
115 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
116 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
117 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
118 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
119 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
120 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
121 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
122};
123
124const char KCodecs::hexChars[16] =
125{
126 '0', '1', '2', '3', '4', '5', '6', '7',
127 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
128};
129
130const unsigned int KCodecs::maxQPLineLength = 70;
131
132
133/******************************** KCodecs ********************************/
134// strchr(3) for broken systems.
135static int rikFindChar(register const char * _s, const char c)
136{
137 register const char * s = _s;
138
139 while (true)
140 {
141 if ((0 == *s) || (c == *s)) break; ++s;
142 if ((0 == *s) || (c == *s)) break; ++s;
143 if ((0 == *s) || (c == *s)) break; ++s;
144 if ((0 == *s) || (c == *s)) break; ++s;
145 }
146
147 return s - _s;
148}
149
150QCString KCodecs::quotedPrintableEncode(const QByteArray& in, bool useCRLF)
151{
152 QByteArray out;
153 quotedPrintableEncode (in, out, useCRLF);
154 return QCString (out.data(), out.size()+1);
155}
156
157QCString KCodecs::quotedPrintableEncode(const QCString& str, bool useCRLF)
158{
159 if (str.isEmpty())
160 return "";
161
162 QByteArray in (str.length());
163 memcpy (in.data(), str.data(), str.length());
164 return quotedPrintableEncode(in, useCRLF);
165}
166
167void KCodecs::quotedPrintableEncode(const QByteArray& in, QByteArray& out, bool useCRLF)
168{
169 out.resize (0);
170 if (in.isEmpty())
171 return;
172
173 char *cursor;
174 const char *data;
175 unsigned int lineLength;
176 unsigned int pos;
177
178 const unsigned int length = in.size();
179 const unsigned int end = length - 1;
180
181
182 // Reasonable guess for output size when we're encoding
183 // mostly-ASCII data. It doesn't really matter, because
184 // the underlying allocation routines are quite efficient,
185 // but it's nice to have 0 allocations in many cases.
186 out.resize ((length*12)/10);
187 cursor = out.data();
188 data = in.data();
189 lineLength = 0;
190 pos = 0;
191
192 for (unsigned int i = 0; i < length; i++)
193 {
194 unsigned char c (data[i]);
195
196 // check if we have to enlarge the output buffer, use
197 // a safety margin of 16 byte
198 pos = cursor-out.data();
199 if (out.size()-pos < 16) {
200 out.resize(out.size()+4096);
201 cursor = out.data()+pos;
202 }
203
204 // Plain ASCII chars just go straight out.
205
206 if ((c >= 33) && (c <= 126) && ('=' != c))
207 {
208 *cursor++ = c;
209 ++lineLength;
210 }
211
212 // Spaces need some thought. We have to encode them at eol (or eof).
213
214 else if (' ' == c)
215 {
216 if
217 (
218 (i >= length)
219 ||
220 ((i < end) && ((useCRLF && ('\r' == data[i + 1]) && ('\n' == data[i + 2]))
221 ||
222 (!useCRLF && ('\n' == data[i + 1]))))
223 )
224 {
225 *cursor++ = '=';
226 *cursor++ = '2';
227 *cursor++ = '0';
228
229 lineLength += 3;
230 }
231 else
232 {
233 *cursor++ = ' ';
234 ++lineLength;
235 }
236 }
237 // If we find a line break, just let it through.
238 else if ((useCRLF && ('\r' == c) && (i < end) && ('\n' == data[i + 1])) ||
239 (!useCRLF && ('\n' == c)))
240 {
241 lineLength = 0;
242
243 if (useCRLF) {
244 *cursor++ = '\r';
245 *cursor++ = '\n';
246 ++i;
247 } else {
248 *cursor++ = '\n';
249 }
250 }
251
252 // Anything else is converted to =XX.
253
254 else
255 {
256 *cursor++ = '=';
257 *cursor++ = hexChars[c / 16];
258 *cursor++ = hexChars[c % 16];
259
260 lineLength += 3;
261 }
262
263 // If we're approaching the maximum line length, do a soft line break.
264
265 if ((lineLength > maxQPLineLength) && (i < end))
266 {
267 if (useCRLF) {
268 *cursor++ = '=';
269 *cursor++ = '\r';
270 *cursor++ = '\n';
271 } else {
272 *cursor++ = '=';
273 *cursor++ = '\n';
274 }
275
276 lineLength = 0;
277 }
278 }
279
280 out.truncate(cursor - out.data());
281}
282
283QCString KCodecs::quotedPrintableDecode(const QByteArray & in)
284{
285 QByteArray out;
286 quotedPrintableDecode (in, out);
287 return QCString (out.data(), out.size()+1);
288}
289
290QCString KCodecs::quotedPrintableDecode(const QCString & str)
291{
292 if (str.isEmpty())
293 return "";
294
295 QByteArray in (str.length());
296 memcpy (in.data(), str.data(), str.length());
297 return quotedPrintableDecode (in);
298}
299
300void KCodecs::quotedPrintableDecode(const QByteArray& in, QByteArray& out)
301{
302 // clear out the output buffer
303 out.resize (0);
304 if (in.isEmpty())
305 return;
306
307 char *cursor;
308 const char *data;
309 const unsigned int length = in.size();
310
311 data = in.data();
312 out.resize (length);
313 cursor = out.data();
314
315 for (unsigned int i = 0; i < length; i++)
316 {
317 char c(in.at(i));
318
319 if ('=' == c)
320 {
321 if (i < length - 2)
322 {
323 char c1 = in.at(i + 1);
324 char c2 = in.at(i + 2);
325
326 if (('\n' == c1) || ('\r' == c1 && '\n' == c2))
327 {
328 // Soft line break. No output.
329 if ('\r' == c1)
330 i += 2; // CRLF line breaks
331 else
332 i += 1;
333 }
334 else
335 {
336 // =XX encoded byte.
337
338 int hexChar0 = rikFindChar(hexChars, c1);
339 int hexChar1 = rikFindChar(hexChars, c2);
340
341 if (hexChar0 < 16 && hexChar1 < 16)
342 {
343 *cursor++ = char((hexChar0 * 16) | hexChar1);
344 i += 2;
345 }
346 }
347 }
348 }
349 else
350 {
351 *cursor++ = c;
352 }
353 }
354
355 out.truncate(cursor - out.data());
356}
357
358QCString KCodecs::base64Encode( const QCString& str, bool insertLFs )
359{
360 if ( str.isEmpty() )
361 return "";
362
363 QByteArray in (str.length());
364 memcpy( in.data(), str.data(), str.length() );
365 return base64Encode( in, insertLFs );
366}
367
368QCString KCodecs::base64Encode( const QByteArray& in, bool insertLFs )
369{
370 QByteArray out;
371 base64Encode( in, out, insertLFs );
372 return QCString( out.data(), out.size()+1 );
373}
374
375void KCodecs::base64Encode( const QByteArray& in, QByteArray& out,
376 bool insertLFs )
377{
378 // clear out the output buffer
379 out.resize (0);
380 if ( in.isEmpty() )
381 return;
382
383 unsigned int sidx = 0;
384 unsigned int didx = 0;
385 const char* data = in.data();
386 const unsigned int len = in.size();
387
388 unsigned int out_len = ((len+2)/3)*4;
389
390 // Deal with the 76 characters or less per
391 // line limit specified in RFC 2045 on a
392 // pre request basis.
393 insertLFs = (insertLFs && out_len > 76);
394 if ( insertLFs )
395 out_len += ((out_len-1)/76);
396
397 int count = 0;
398 out.resize( out_len );
399
400 // 3-byte to 4-byte conversion + 0-63 to ascii printable conversion
401 if ( len > 1 )
402 {
403 while (sidx < len-2)
404 {
405 if ( insertLFs )
406 {
407 if ( count && (count%76) == 0 )
408 out.at(didx++) = '\n';
409 count += 4;
410 }
411 out.at(didx++) = Base64EncMap[(data[sidx] >> 2) & 077];
412 out.at(didx++) = Base64EncMap[(data[sidx+1] >> 4) & 017 |
413 (data[sidx] << 4) & 077];
414 out.at(didx++) = Base64EncMap[(data[sidx+2] >> 6) & 003 |
415 (data[sidx+1] << 2) & 077];
416 out.at(didx++) = Base64EncMap[data[sidx+2] & 077];
417 sidx += 3;
418 }
419 }
420
421 if (sidx < len)
422 {
423 if ( insertLFs && (count > 0) && (count%76) == 0 )
424 out.at(didx++) = '\n';
425
426 out.at(didx++) = Base64EncMap[(data[sidx] >> 2) & 077];
427 if (sidx < len-1)
428 {
429 out.at(didx++) = Base64EncMap[(data[sidx+1] >> 4) & 017 |
430 (data[sidx] << 4) & 077];
431 out.at(didx++) = Base64EncMap[(data[sidx+1] << 2) & 077];
432 }
433 else
434 {
435 out.at(didx++) = Base64EncMap[(data[sidx] << 4) & 077];
436 }
437 }
438
439 // Add padding
440 while (didx < out.size())
441 {
442 out.at(didx) = '=';
443 didx++;
444 }
445}
446
447QCString KCodecs::base64Decode( const QCString& str )
448{
449 if ( str.isEmpty() )
450 return "";
451
452 QByteArray in( str.length() );
453 memcpy( in.data(), str.data(), str.length() );
454 return base64Decode( in );
455}
456
457QCString KCodecs::base64Decode( const QByteArray& in )
458{
459 QByteArray out;
460 base64Decode( in, out );
461 return QCString( out.data(), out.size()+1 );
462}
463
464void KCodecs::base64Decode( const QByteArray& in, QByteArray& out )
465{
466 out.resize(0);
467 if ( in.isEmpty() )
468 return;
469
470 unsigned int count = 0;
471 unsigned int len = in.size(), tail = len;
472 const char* data = in.data();
473
474 // Deal with possible *nix "BEGIN" marker!!
475 while ( count < len && (data[count] == '\n' || data[count] == '\r' ||
476 data[count] == '\t' || data[count] == ' ') )
477 count++;
478
479 if ( QString(data+count).left(5).lower() == "begin" )
480 {
481 count += 5;
482 while ( count < len && data[count] != '\n' && data[count] != '\r' )
483 count++;
484
485 while ( count < len && (data[count] == '\n' || data[count] == '\r') )
486 count ++;
487
488 data += count;
489 tail = (len -= count);
490 }
491
492 // Find the tail end of the actual encoded data even if
493 // there is/are trailing CR and/or LF.
494 while ( data[tail-1] == '=' || data[tail-1] == '\n' ||
495 data[tail-1] == '\r' )
496 if ( data[--tail] != '=' ) len = tail;
497
498 unsigned int outIdx = 0;
499 out.resize( (count=len) );
500 for (unsigned int idx = 0; idx < count; idx++)
501 {
502 // Adhere to RFC 2045 and ignore characters
503 // that are not part of the encoding table.
504 unsigned char ch = data[idx];
505 if ((ch > 47 && ch < 58) || (ch > 64 && ch < 91) ||
506 (ch > 96 && ch < 123) || ch == '+' || ch == '/' || ch == '=')
507 {
508 out.at(outIdx++) = Base64DecMap[ch];
509 }
510 else
511 {
512 len--;
513 tail--;
514 }
515 }
516
517 // kdDebug() << "Tail size = " << tail << ", Length size = " << len << endl;
518
519 // 4-byte to 3-byte conversion
520 len = (tail>(len/4)) ? tail-(len/4) : 0;
521 unsigned int sidx = 0, didx = 0;
522 if ( len > 1 )
523 {
524 while (didx < len-2)
525 {
526 out.at(didx) = (((out.at(sidx) << 2) & 255) | ((out.at(sidx+1) >> 4) & 003));
527 out.at(didx+1) = (((out.at(sidx+1) << 4) & 255) | ((out.at(sidx+2) >> 2) & 017));
528 out.at(didx+2) = (((out.at(sidx+2) << 6) & 255) | (out.at(sidx+3) & 077));
529 sidx += 4;
530 didx += 3;
531 }
532 }
533
534 if (didx < len)
535 out.at(didx) = (((out.at(sidx) << 2) & 255) | ((out.at(sidx+1) >> 4) & 003));
536
537 if (++didx < len )
538 out.at(didx) = (((out.at(sidx+1) << 4) & 255) | ((out.at(sidx+2) >> 2) & 017));
539
540 // Resize the output buffer
541 if ( len == 0 || len < out.size() )
542 out.resize(len);
543}
544
545QCString KCodecs::uuencode( const QCString& str )
546{
547 if ( str.isEmpty() )
548 return "";
549
550 QByteArray in;
551 in.resize( str.length() );
552 memcpy( in.data(), str.data(), str.length() );
553 return uuencode( in );
554}
555
556QCString KCodecs::uuencode( const QByteArray& in )
557{
558 QByteArray out;
559 uuencode( in, out );
560 return QCString( out.data(), out.size()+1 );
561}
562
563void KCodecs::uuencode( const QByteArray& in, QByteArray& out )
564{
565 out.resize( 0 );
566 if( in.isEmpty() )
567 return;
568
569 unsigned int sidx = 0;
570 unsigned int didx = 0;
571 unsigned int line_len = 45;
572
573 const char nl[] = "\n";
574 const char* data = in.data();
575 const unsigned int nl_len = strlen(nl);
576 const unsigned int len = in.size();
577
578 out.resize( (len+2)/3*4 + ((len+line_len-1)/line_len)*(nl_len+1) );
579 // split into lines, adding line-length and line terminator
580 while (sidx+line_len < len)
581 {
582 // line length
583 out.at(didx++) = UUEncMap[line_len];
584
585 // 3-byte to 4-byte conversion + 0-63 to ascii printable conversion
586 for (unsigned int end = sidx+line_len; sidx < end; sidx += 3)
587 {
588 out.at(didx++) = UUEncMap[(data[sidx] >> 2) & 077];
589 out.at(didx++) = UUEncMap[(data[sidx+1] >> 4) & 017 |
590 (data[sidx] << 4) & 077];
591 out.at(didx++) = UUEncMap[(data[sidx+2] >> 6) & 003 |
592 (data[sidx+1] << 2) & 077];
593 out.at(didx++) = UUEncMap[data[sidx+2] & 077];
594 }
595
596 // line terminator
597 //for (unsigned int idx=0; idx < nl_len; idx++)
598 //out.at(didx++) = nl[idx];
599 memcpy(out.data()+didx, nl, nl_len);
600 didx += nl_len;
601 }
602
603 // line length
604 out.at(didx++) = UUEncMap[len-sidx];
605 // 3-byte to 4-byte conversion + 0-63 to ascii printable conversion
606 while (sidx+2 < len)
607 {
608 out.at(didx++) = UUEncMap[(data[sidx] >> 2) & 077];
609 out.at(didx++) = UUEncMap[(data[sidx+1] >> 4) & 017 |
610 (data[sidx] << 4) & 077];
611 out.at(didx++) = UUEncMap[(data[sidx+2] >> 6) & 003 |
612 (data[sidx+1] << 2) & 077];
613 out.at(didx++) = UUEncMap[data[sidx+2] & 077];
614 sidx += 3;
615 }
616
617 if (sidx < len-1)
618 {
619 out.at(didx++) = UUEncMap[(data[sidx] >> 2) & 077];
620 out.at(didx++) = UUEncMap[(data[sidx+1] >> 4) & 017 |
621 (data[sidx] << 4) & 077];
622 out.at(didx++) = UUEncMap[(data[sidx+1] << 2) & 077];
623 out.at(didx++) = UUEncMap[0];
624 }
625 else if (sidx < len)
626 {
627 out.at(didx++) = UUEncMap[(data[sidx] >> 2) & 077];
628 out.at(didx++) = UUEncMap[(data[sidx] << 4) & 077];
629 out.at(didx++) = UUEncMap[0];
630 out.at(didx++) = UUEncMap[0];
631 }
632
633 // line terminator
634 memcpy(out.data()+didx, nl, nl_len);
635 didx += nl_len;
636
637 // sanity check
638 if ( didx != out.size() )
639 out.resize( 0 );
640}
641
642QCString KCodecs::uudecode( const QCString& str )
643{
644 if ( str.isEmpty() )
645 return "";
646
647 QByteArray in;
648 in.resize( str.length() );
649 memcpy( in.data(), str.data(), str.length() );
650 return uudecode( in );
651}
652
653QCString KCodecs::uudecode( const QByteArray& in )
654{
655 QByteArray out;
656 uudecode( in, out );
657 return QCString( out.data(), out.size()+1 );
658}
659
660void KCodecs::uudecode( const QByteArray& in, QByteArray& out )
661{
662 out.resize( 0 );
663 if( in.isEmpty() )
664 return;
665
666 unsigned int sidx = 0;
667 unsigned int didx = 0;
668 unsigned int len = in.size();
669 unsigned int line_len, end;
670 const char* data = in.data();
671
672 // Deal with *nix "BEGIN"/"END" separators!!
673 unsigned int count = 0;
674 while ( count < len && (data[count] == '\n' || data[count] == '\r' ||
675 data[count] == '\t' || data[count] == ' ') )
676 count ++;
677
678 bool hasLF = false;
679 if ( QString( data+count).left(5).lower() == "begin" )
680 {
681 count += 5;
682 while ( count < len && data[count] != '\n' && data[count] != '\r' )
683 count ++;
684
685 while ( count < len && (data[count] == '\n' || data[count] == '\r') )
686 count ++;
687
688 data += count;
689 len -= count;
690 hasLF = true;
691 }
692
693 out.resize( len/4*3 );
694 while ( sidx < len )
695 {
696 // get line length (in number of encoded octets)
697 line_len = UUDecMap[ (unsigned char) data[sidx++]];
698 // ascii printable to 0-63 and 4-byte to 3-byte conversion
699 end = didx+line_len;
700 char A, B, C, D;
701 if (end > 2) {
702 while (didx < end-2)
703 {
704 A = UUDecMap[(unsigned char) data[sidx]];
705 B = UUDecMap[(unsigned char) data[sidx+1]];
706 C = UUDecMap[(unsigned char) data[sidx+2]];
707 D = UUDecMap[(unsigned char) data[sidx+3]];
708 out.at(didx++) = ( ((A << 2) & 255) | ((B >> 4) & 003) );
709 out.at(didx++) = ( ((B << 4) & 255) | ((C >> 2) & 017) );
710 out.at(didx++) = ( ((C << 6) & 255) | (D & 077) );
711 sidx += 4;
712 }
713 }
714
715 if (didx < end)
716 {
717 A = UUDecMap[(unsigned char) data[sidx]];
718 B = UUDecMap[(unsigned char) data[sidx+1]];
719 out.at(didx++) = ( ((A << 2) & 255) | ((B >> 4) & 003) );
720 }
721
722 if (didx < end)
723 {
724 B = UUDecMap[(unsigned char) data[sidx+1]];
725 C = UUDecMap[(unsigned char) data[sidx+2]];
726 out.at(didx++) = ( ((B << 4) & 255) | ((C >> 2) & 017) );
727 }
728
729 // skip padding
730 while (sidx < len && data[sidx] != '\n' && data[sidx] != '\r')
731 sidx++;
732
733 // skip end of line
734 while (sidx < len && (data[sidx] == '\n' || data[sidx] == '\r'))
735 sidx++;
736
737 // skip the "END" separator when present.
738 if ( hasLF && QString( data+sidx).left(3).lower() == "end" )
739 break;
740 }
741
742 if ( didx < out.size() )
743 out.resize( didx );
744}
745
746/******************************** KMD5 ********************************/
747KMD5::KMD5()
748{
749 init();
750}
751
752KMD5::KMD5(const char *in, int len)
753{
754 init();
755 update(in, len);
756}
757
758KMD5::KMD5(const QByteArray& in)
759{
760 init();
761 update( in );
762}
763
764KMD5::KMD5(const QCString& in)
765{
766 init();
767 update( in );
768}
769
770void KMD5::update(const QByteArray& in)
771{
772 update(in.data(), int(in.size()));
773}
774
775void KMD5::update(const QCString& in)
776{
777 update(in.data(), int(in.length()));
778}
779
780void KMD5::update(const unsigned char* in, int len)
781{
782 if (len < 0)
783 len = qstrlen(reinterpret_cast<const char*>(in));
784
785 if (!len)
786 return;
787
788 if (m_finalized) {
789 kdWarning() << "KMD5::update called after state was finalized!" << endl;
790 return;
791 }
792
793 Q_UINT32 in_index;
794 Q_UINT32 buffer_index;
795 Q_UINT32 buffer_space;
796 Q_UINT32 in_length = static_cast<Q_UINT32>( len );
797
798 buffer_index = static_cast<Q_UINT32>((m_count[0] >> 3) & 0x3F);
799
800 if ( (m_count[0] += (in_length << 3))<(in_length << 3) )
801 m_count[1]++;
802
803 m_count[1] += (in_length >> 29);
804 buffer_space = 64 - buffer_index;
805
806 if (in_length >= buffer_space)
807 {
808 memcpy (m_buffer + buffer_index, in, buffer_space);
809 transform (m_buffer);
810
811 for (in_index = buffer_space; in_index + 63 < in_length;
812 in_index += 64)
813 transform (reinterpret_cast<const unsigned char*>(in+in_index));
814
815 buffer_index = 0;
816 }
817 else
818 in_index=0;
819
820 memcpy(m_buffer+buffer_index, in+in_index, in_length-in_index);
821}
822
823bool KMD5::update(QIODevice& file)
824{
825 char buffer[1024];
826 int len;
827
828 while ((len=file.readBlock(reinterpret_cast<char*>(buffer), sizeof(buffer))) > 0)
829 update(buffer, len);
830
831 return file.atEnd();
832}
833
834void KMD5::finalize ()
835{
836 if (m_finalized) return;
837
838 Q_UINT8 bits[8];
839 Q_UINT32 index, padLen;
840 static unsigned char PADDING[64]=
841 {
842 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
843 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
844 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
845 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
846 };
847
848 encode (bits, m_count, 8);
849 //memcpy( bits, m_count, 8 );
850
851 // Pad out to 56 mod 64.
852 index = static_cast<Q_UINT32>((m_count[0] >> 3) & 0x3f);
853 padLen = (index < 56) ? (56 - index) : (120 - index);
854 update (reinterpret_cast<const char*>(PADDING), padLen);
855
856 // Append length (before padding)
857 update (reinterpret_cast<const char*>(bits), 8);
858
859 // Store state in digest
860 encode (m_digest, m_state, 16);
861 //memcpy( m_digest, m_state, 16 );
862
863 // Fill sensitive information with zero's
864 memset ( (void *)m_buffer, 0, sizeof(*m_buffer));
865
866 m_finalized = true;
867}
868
869
870bool KMD5::verify( const KMD5::Digest& digest)
871{
872 finalize();
873 return (0 == memcmp(rawDigest(), digest, sizeof(KMD5::Digest)));
874}
875
876bool KMD5::verify( const QCString& hexdigest)
877{
878 finalize();
879 return (0 == strcmp(hexDigest().data(), hexdigest));
880}
881
882const KMD5::Digest& KMD5::rawDigest()
883{
884 finalize();
885 return m_digest;
886}
887
888void KMD5::rawDigest( KMD5::Digest& bin )
889{
890 finalize();
891 memcpy( bin, m_digest, 16 );
892}
893
894
895QCString KMD5::hexDigest()
896{
897 QCString s(33);
898
899 finalize();
900 sprintf(s.data(), "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
901 m_digest[0], m_digest[1], m_digest[2], m_digest[3], m_digest[4], m_digest[5],
902 m_digest[6], m_digest[7], m_digest[8], m_digest[9], m_digest[10], m_digest[11],
903 m_digest[12], m_digest[13], m_digest[14], m_digest[15]);
904
905 return s;
906}
907
908void KMD5::hexDigest(QCString& s)
909{
910 finalize();
911 s.resize(33);
912 sprintf(s.data(), "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
913 m_digest[0], m_digest[1], m_digest[2], m_digest[3], m_digest[4], m_digest[5],
914 m_digest[6], m_digest[7], m_digest[8], m_digest[9], m_digest[10], m_digest[11],
915 m_digest[12], m_digest[13], m_digest[14], m_digest[15]);
916}
917
918QCString KMD5::base64Digest()
919{
920 QByteArray ba(16);
921
922 finalize();
923 memcpy(ba.data(), m_digest, 16);
924 return KCodecs::base64Encode(ba);
925}
926
927
928void KMD5::init()
929{
930 d = 0;
931 reset();
932}
933
934void KMD5::reset()
935{
936 m_finalized = false;
937
938 m_count[0] = 0;
939 m_count[1] = 0;
940
941 m_state[0] = 0x67452301;
942 m_state[1] = 0xefcdab89;
943 m_state[2] = 0x98badcfe;
944 m_state[3] = 0x10325476;
945
946 memset ( m_buffer, 0, sizeof(*m_buffer));
947 memset ( m_digest, 0, sizeof(*m_digest));
948}
949
950void KMD5::transform( const unsigned char block[64] )
951{
952
953 Q_UINT32 a = m_state[0], b = m_state[1], c = m_state[2], d = m_state[3], x[16];
954
955 decode (x, block, 64);
956 //memcpy( x, block, 64 );
957
958//US Q_ASSERT(!m_finalized); // not just a user error, since the method is private
959 ASSERT(!m_finalized); // not just a user error, since the method is private
960
961 /* Round 1 */
962 FF (a, b, c, d, x[ 0], KMD5_S11, 0xd76aa478); /* 1 */
963 FF (d, a, b, c, x[ 1], KMD5_S12, 0xe8c7b756); /* 2 */
964 FF (c, d, a, b, x[ 2], KMD5_S13, 0x242070db); /* 3 */
965 FF (b, c, d, a, x[ 3], KMD5_S14, 0xc1bdceee); /* 4 */
966 FF (a, b, c, d, x[ 4], KMD5_S11, 0xf57c0faf); /* 5 */
967 FF (d, a, b, c, x[ 5], KMD5_S12, 0x4787c62a); /* 6 */
968 FF (c, d, a, b, x[ 6], KMD5_S13, 0xa8304613); /* 7 */
969 FF (b, c, d, a, x[ 7], KMD5_S14, 0xfd469501); /* 8 */
970 FF (a, b, c, d, x[ 8], KMD5_S11, 0x698098d8); /* 9 */
971 FF (d, a, b, c, x[ 9], KMD5_S12, 0x8b44f7af); /* 10 */
972 FF (c, d, a, b, x[10], KMD5_S13, 0xffff5bb1); /* 11 */
973 FF (b, c, d, a, x[11], KMD5_S14, 0x895cd7be); /* 12 */
974 FF (a, b, c, d, x[12], KMD5_S11, 0x6b901122); /* 13 */
975 FF (d, a, b, c, x[13], KMD5_S12, 0xfd987193); /* 14 */
976 FF (c, d, a, b, x[14], KMD5_S13, 0xa679438e); /* 15 */
977 FF (b, c, d, a, x[15], KMD5_S14, 0x49b40821); /* 16 */
978
979 /* Round 2 */
980 GG (a, b, c, d, x[ 1], KMD5_S21, 0xf61e2562); /* 17 */
981 GG (d, a, b, c, x[ 6], KMD5_S22, 0xc040b340); /* 18 */
982 GG (c, d, a, b, x[11], KMD5_S23, 0x265e5a51); /* 19 */
983 GG (b, c, d, a, x[ 0], KMD5_S24, 0xe9b6c7aa); /* 20 */
984 GG (a, b, c, d, x[ 5], KMD5_S21, 0xd62f105d); /* 21 */
985 GG (d, a, b, c, x[10], KMD5_S22, 0x2441453); /* 22 */
986 GG (c, d, a, b, x[15], KMD5_S23, 0xd8a1e681); /* 23 */
987 GG (b, c, d, a, x[ 4], KMD5_S24, 0xe7d3fbc8); /* 24 */
988 GG (a, b, c, d, x[ 9], KMD5_S21, 0x21e1cde6); /* 25 */
989 GG (d, a, b, c, x[14], KMD5_S22, 0xc33707d6); /* 26 */
990 GG (c, d, a, b, x[ 3], KMD5_S23, 0xf4d50d87); /* 27 */
991 GG (b, c, d, a, x[ 8], KMD5_S24, 0x455a14ed); /* 28 */
992 GG (a, b, c, d, x[13], KMD5_S21, 0xa9e3e905); /* 29 */
993 GG (d, a, b, c, x[ 2], KMD5_S22, 0xfcefa3f8); /* 30 */
994 GG (c, d, a, b, x[ 7], KMD5_S23, 0x676f02d9); /* 31 */
995 GG (b, c, d, a, x[12], KMD5_S24, 0x8d2a4c8a); /* 32 */
996
997 /* Round 3 */
998 HH (a, b, c, d, x[ 5], KMD5_S31, 0xfffa3942); /* 33 */
999 HH (d, a, b, c, x[ 8], KMD5_S32, 0x8771f681); /* 34 */
1000 HH (c, d, a, b, x[11], KMD5_S33, 0x6d9d6122); /* 35 */
1001 HH (b, c, d, a, x[14], KMD5_S34, 0xfde5380c); /* 36 */
1002 HH (a, b, c, d, x[ 1], KMD5_S31, 0xa4beea44); /* 37 */
1003 HH (d, a, b, c, x[ 4], KMD5_S32, 0x4bdecfa9); /* 38 */
1004 HH (c, d, a, b, x[ 7], KMD5_S33, 0xf6bb4b60); /* 39 */
1005 HH (b, c, d, a, x[10], KMD5_S34, 0xbebfbc70); /* 40 */
1006 HH (a, b, c, d, x[13], KMD5_S31, 0x289b7ec6); /* 41 */
1007 HH (d, a, b, c, x[ 0], KMD5_S32, 0xeaa127fa); /* 42 */
1008 HH (c, d, a, b, x[ 3], KMD5_S33, 0xd4ef3085); /* 43 */
1009 HH (b, c, d, a, x[ 6], KMD5_S34, 0x4881d05); /* 44 */
1010 HH (a, b, c, d, x[ 9], KMD5_S31, 0xd9d4d039); /* 45 */
1011 HH (d, a, b, c, x[12], KMD5_S32, 0xe6db99e5); /* 46 */
1012 HH (c, d, a, b, x[15], KMD5_S33, 0x1fa27cf8); /* 47 */
1013 HH (b, c, d, a, x[ 2], KMD5_S34, 0xc4ac5665); /* 48 */
1014
1015 /* Round 4 */
1016 II (a, b, c, d, x[ 0], KMD5_S41, 0xf4292244); /* 49 */
1017 II (d, a, b, c, x[ 7], KMD5_S42, 0x432aff97); /* 50 */
1018 II (c, d, a, b, x[14], KMD5_S43, 0xab9423a7); /* 51 */
1019 II (b, c, d, a, x[ 5], KMD5_S44, 0xfc93a039); /* 52 */
1020 II (a, b, c, d, x[12], KMD5_S41, 0x655b59c3); /* 53 */
1021 II (d, a, b, c, x[ 3], KMD5_S42, 0x8f0ccc92); /* 54 */
1022 II (c, d, a, b, x[10], KMD5_S43, 0xffeff47d); /* 55 */
1023 II (b, c, d, a, x[ 1], KMD5_S44, 0x85845dd1); /* 56 */
1024 II (a, b, c, d, x[ 8], KMD5_S41, 0x6fa87e4f); /* 57 */
1025 II (d, a, b, c, x[15], KMD5_S42, 0xfe2ce6e0); /* 58 */
1026 II (c, d, a, b, x[ 6], KMD5_S43, 0xa3014314); /* 59 */
1027 II (b, c, d, a, x[13], KMD5_S44, 0x4e0811a1); /* 60 */
1028 II (a, b, c, d, x[ 4], KMD5_S41, 0xf7537e82); /* 61 */
1029 II (d, a, b, c, x[11], KMD5_S42, 0xbd3af235); /* 62 */
1030 II (c, d, a, b, x[ 2], KMD5_S43, 0x2ad7d2bb); /* 63 */
1031 II (b, c, d, a, x[ 9], KMD5_S44, 0xeb86d391); /* 64 */
1032
1033 m_state[0] += a;
1034 m_state[1] += b;
1035 m_state[2] += c;
1036 m_state[3] += d;
1037
1038 memset ( static_cast<void *>(x), 0, sizeof(x) );
1039}
1040
1041inline Q_UINT32 KMD5::rotate_left (Q_UINT32 x, Q_UINT32 n)
1042{
1043 return (x << n) | (x >> (32-n)) ;
1044}
1045
1046inline Q_UINT32 KMD5::F (Q_UINT32 x, Q_UINT32 y, Q_UINT32 z)
1047{
1048 return (x & y) | (~x & z);
1049}
1050
1051inline Q_UINT32 KMD5::G (Q_UINT32 x, Q_UINT32 y, Q_UINT32 z)
1052{
1053 return (x & z) | (y & ~z);
1054}
1055
1056inline Q_UINT32 KMD5::H (Q_UINT32 x, Q_UINT32 y, Q_UINT32 z)
1057{
1058 return x ^ y ^ z;
1059}
1060
1061inline Q_UINT32 KMD5::I (Q_UINT32 x, Q_UINT32 y, Q_UINT32 z)
1062{
1063 return y ^ (x | ~z);
1064}
1065
1066void KMD5::FF ( Q_UINT32& a, Q_UINT32 b, Q_UINT32 c, Q_UINT32 d,
1067 Q_UINT32 x, Q_UINT32 s, Q_UINT32 ac )
1068{
1069 a += F(b, c, d) + x + ac;
1070 a = rotate_left (a, s) +b;
1071}
1072
1073void KMD5::GG ( Q_UINT32& a, Q_UINT32 b, Q_UINT32 c, Q_UINT32 d,
1074 Q_UINT32 x, Q_UINT32 s, Q_UINT32 ac)
1075{
1076 a += G(b, c, d) + x + ac;
1077 a = rotate_left (a, s) +b;
1078}
1079
1080void KMD5::HH ( Q_UINT32& a, Q_UINT32 b, Q_UINT32 c, Q_UINT32 d,
1081 Q_UINT32 x, Q_UINT32 s, Q_UINT32 ac )
1082{
1083 a += H(b, c, d) + x + ac;
1084 a = rotate_left (a, s) +b;
1085}
1086
1087void KMD5::II ( Q_UINT32& a, Q_UINT32 b, Q_UINT32 c, Q_UINT32 d,
1088 Q_UINT32 x, Q_UINT32 s, Q_UINT32 ac )
1089{
1090 a += I(b, c, d) + x + ac;
1091 a = rotate_left (a, s) +b;
1092}
1093
1094
1095void KMD5::encode ( unsigned char* output, Q_UINT32 *in, Q_UINT32 len )
1096{
1097#if !defined(WORDS_BIGENDIAN)
1098 memcpy(output, in, len);
1099
1100#else
1101 Q_UINT32 i, j;
1102 for (i = 0, j = 0; j < len; i++, j += 4)
1103 {
1104 output[j] = static_cast<Q_UINT8>((in[i] & 0xff));
1105 output[j+1] = static_cast<Q_UINT8>(((in[i] >> 8) & 0xff));
1106 output[j+2] = static_cast<Q_UINT8>(((in[i] >> 16) & 0xff));
1107 output[j+3] = static_cast<Q_UINT8>(((in[i] >> 24) & 0xff));
1108 }
1109#endif
1110}
1111
1112// Decodes in (Q_UINT8) into output (Q_UINT32). Assumes len is a
1113// multiple of 4.
1114void KMD5::decode (Q_UINT32 *output, const unsigned char* in, Q_UINT32 len)
1115{
1116#if !defined(WORDS_BIGENDIAN)
1117 memcpy(output, in, len);
1118
1119#else
1120 Q_UINT32 i, j;
1121 for (i = 0, j = 0; j < len; i++, j += 4)
1122 output[i] = static_cast<Q_UINT32>(in[j]) |
1123 (static_cast<Q_UINT32>(in[j+1]) << 8) |
1124 (static_cast<Q_UINT32>(in[j+2]) << 16) |
1125 (static_cast<Q_UINT32>(in[j+3]) << 24);
1126#endif
1127}
diff --git a/microkde/kdecore/kmdcodec.h b/microkde/kdecore/kmdcodec.h
new file mode 100644
index 0000000..2c4d611
--- a/dev/null
+++ b/microkde/kdecore/kmdcodec.h
@@ -0,0 +1,572 @@
1/*
2 Copyright (C) 2000-2001 Dawit Alemayehu <adawit@kde.org>
3 Copyright (C) 2001 Rik Hemsley (rikkus) <rik@kde.org>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License (LGPL)
7 version 2 as published by the Free Software Foundation.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public
15 License along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18 RFC 1321 "MD5 Message-Digest Algorithm" Copyright (C) 1991-1992.
19 RSA Data Security, Inc. Created 1991. All rights reserved.
20
21 The KMD5 class is based on a C++ implementation of
22 "RSA Data Security, Inc. MD5 Message-Digest Algorithm" by
23 Mordechai T. Abzug,Copyright (c) 1995. This implementation
24 passes the test-suite as defined in RFC 1321.
25
26 The encoding and decoding utilities in KCodecs with the exception of
27 quoted-printable are based on the java implementation in HTTPClient
28 package by Ronald Tschalär Copyright (C) 1996-1999.
29
30 The quoted-printable codec as described in RFC 2045, section 6.7. is by
31 Rik Hemsley (C) 2001.
32*/
33
34#ifndef _KMDBASE_H
35#define _KMDBASE_H
36
37#define KBase64 KCodecs
38
39#include <qglobal.h>
40#include <qstring.h>
41#include <qiodevice.h>
42
43/**
44 * A wrapper class for the most commonly used encoding and
45 * decoding algorithms. Currently there is support for encoding
46 * and decoding input using base64, uu and the quoted-printable
47 * specifications.
48 *
49 * @sect Usage:
50 *
51 * <PRE>
52 * QCString input = "Aladdin:open sesame";
53 * QCString result = KCodecs::base64Encode(input);
54 * cout << "Result: " << result.data() << endl;
55 *
56 * Output should be
57 * Result: QWxhZGRpbjpvcGVuIHNlc2FtZQ==
58 * </PRE>
59 *
60 * The above example makes use of the convenience functions
61 * (ones that accept/return null-terminated strings) to encode/decode
62 * a string. If what you need is to encode or decode binary data, then
63 * it is highly recommended that you use the functions that take an input
64 * and output QByteArray as arguments. These functions are specifically
65 * tailored for encoding and decoding binary data.
66 *
67 * @short A collection of commonly used encoding and decoding algorithms.
68 * @author Dawit Alemayehu <adawit@kde.org>
69 * @author Rik Hemsley <rik@kde.org>
70 */
71class KCodecs
72{
73public:
74
75 /**
76 * Encodes the given data using the quoted-printable algorithm.
77 *
78 * @param in data to be encoded.
79 * @param useCRLF if true the input data is expected to have
80 * CRLF line breaks and the output will have CRLF line
81 * breaks, too.
82 * @return quoted-printable encoded data.
83 */
84 static QCString quotedPrintableEncode(const QByteArray & in,
85 bool useCRLF = true);
86
87 /**
88 * @overload
89 *
90 * Same as above except it accepts a null terminated
91 * string instead an array.
92 *
93 * @param str data to be encoded.
94 * @param useCRLF if true the input data is expected to have
95 * CRLF line breaks and the output will have CRLF line
96 * breaks, too.
97 * @return quoted-printable encoded data.
98 */
99 static QCString quotedPrintableEncode(const QCString & str,
100 bool useCRLF = true);
101
102 /**
103 * Encodes the given data using the quoted-printable algorithm.
104 *
105 * Use this function if you want the result of the encoding
106 * to be placed in another array which cuts down the number
107 * of copy operation that have to be performed in the process.
108 * This is also the preferred method for encoding binary data.
109 *
110 * NOTE: the output array is first reset and then resized
111 * appropriately before use, hence, all data stored in the
112 * output array will be lost.
113 *
114 * @param in data to be encoded.
115 * @param out decoded data.
116 * @param useCRLF if true the input data is expected to have
117 * CRLF line breaks and the output will have CRLF line
118 * breaks, too.
119 * @return quoted-printable encoded data.
120 */
121 static void quotedPrintableEncode(const QByteArray & in, QByteArray& out,
122 bool useCRLF);
123
124 /**
125 * Decodes a quoted-printable encoded string.
126 *
127 * Accepts data with CRLF or standard unix line breaks.
128 *
129 * @param in the data to be decoded.
130 * @return decoded data.
131 */
132 static QCString quotedPrintableDecode(const QByteArray & in);
133
134 /**
135 * @overload
136 *
137 * Same as above except it accepts a null terminated
138 * string instead an array.
139 *
140 * @param str the data to be decoded.
141 * @return decoded data.
142 */
143 static QCString quotedPrintableDecode(const QCString & str);
144
145 /**
146 * Decodes a quoted-printable encoded data.
147 *
148 * Accepts data with CRLF or standard unix line breaks.
149 * Use this function if you want the result of the decoding
150 * to be placed in another array which cuts down the number
151 * of copy operation that have to be performed in the process.
152 * This is also the preferred method for decoding an encoded
153 * binary data.
154 *
155 * NOTE: the output array is first reset and then resized
156 * appropriately before use, hence, all data stored in the
157 * output array will be lost.
158 *
159 * @param in data to be encoded.
160 * @param out decoded data.
161 *
162 * @return quoted-printable encoded data.
163 */
164 static void quotedPrintableDecode(const QByteArray & in, QByteArray& out);
165
166
167 /**
168 * Encodes the given data using the uuencode algorithm.
169 *
170 * The output is split into lines starting with the number of
171 * encoded octets in the line and ending with a newline. No
172 * line is longer than 45 octets (60 characters), excluding the
173 * line terminator.
174 *
175 * @param in the data to be uuencoded
176 * @return a uuencoded data.
177 */
178 static QCString uuencode( const QByteArray& in );
179
180 /**
181 * @overload
182 *
183 * Same as the above functions except it accepts
184 * a null terminated string instead an array.
185 *
186 * @param str the string to be uuencoded.
187 * @return the encoded string.
188 */
189 static QCString uuencode( const QCString& str );
190
191 /**
192 * Encodes the given data using the uuencode algorithm.
193 *
194 * Use this function if you want the result of the encoding
195 * to be placed in another array and cut down the number of
196 * copy operation that have to be performed in the process.
197 * This is the preffered method for encoding binary data.
198 *
199 * NOTE: the output array is first reset and then resized
200 * appropriately before use, hence, all data stored in the
201 * output array will be lost.
202 *
203 * @param in the data to be uuencoded.
204 * @param out the container for the uudecoded data.
205 */
206 static void uuencode( const QByteArray& in, QByteArray& out );
207
208 /**
209 * Decodes the given data using the uuencode algorithm.
210 *
211 * Any 'begin' and 'end' lines like those generated by
212 * the utilities in unix and unix-like OS will be
213 * automatically ignored.
214 *
215 * @param in the data uuencoded data to be decoded.
216 * @return a decoded string.
217 */
218 static QCString uudecode( const QByteArray& in );
219
220 /**
221 * @overload
222 *
223 * Same as the above functions except it accepts
224 * a null terminated string instead an array.
225 *
226 * @param str the string to be decoded.
227 * @return a uudecoded string.
228 */
229 static QCString uudecode( const QCString& str );
230
231 /**
232 * Decodes the given data using the uudecode algorithm.
233 *
234 * Use this function if you want the result of the decoding
235 * to be placed in another array which cuts down the number
236 * of copy operation that have to be performed in the process.
237 * This is the preferred method for decoding binary data.
238 *
239 * Any 'begin' and 'end' lines like those generated by
240 * the utilities in unix and unix-like OS will be
241 * automatically ignored.
242 *
243 * NOTE: the output array is first reset and then resized
244 * appropriately before use, hence, all data stored in the
245 * output array will be lost.
246 *
247 * @param in the uuencoded-data to be decoded.
248 * @param out the container for the uudecoded data.
249 */
250 static void uudecode( const QByteArray& in, QByteArray& out );
251
252
253 /**
254 * Encodes the given data using the base64 algorithm.
255 *
256 * The boolean argument determines if the encoded data is
257 * going to be restricted to 76 characters or less per line
258 * as specified by RFC 2045. If @p insertLFs is true, then
259 * there will be 76 characters or less per line.
260 *
261 * @param in the data to be encoded.
262 * @param insertLFs limit the number of characters per line.
263 *
264 * @return a base64 encoded string.
265 */
266 static QCString base64Encode( const QByteArray& in, bool insertLFs = false);
267
268 /**
269 * @overload
270 *
271 * Same as the above functions except it accepts
272 * a null terminated string instead an array.
273 *
274 * @param str the string to be encoded.
275 * @param insertLFs limit the number of characters per line.
276 * @return the decoded string.
277 */
278 static QCString base64Encode( const QCString& str, bool insertLFs = false );
279
280 /**
281 * Encodes the given data using the base64 algorithm.
282 *
283 * Use this function if you want the result of the encoding
284 * to be placed in another array which cuts down the number
285 * of copy operation that have to be performed in the process.
286 * This is also the preferred method for encoding binary data.
287 *
288 * The boolean argument determines if the encoded data is going
289 * to be restricted to 76 characters or less per line as specified
290 * by RFC 2045. If @p insertLFs is true, then there will be 76
291 * characters or less per line.
292 *
293 * NOTE: the output array is first reset and then resized
294 * appropriately before use, hence, all data stored in the
295 * output array will be lost.
296 *
297 * @param in the data to be encoded using base64.
298 * @param out the container for the encoded data.
299 * @param insertLFs limit the number of characters per line.
300 */
301 static void base64Encode( const QByteArray& in, QByteArray& out,
302 bool insertLFs = false );
303
304 /**
305 * Decodes the given data that was encoded using the
306 * base64 algorithm.
307 *
308 * @param in the base64-encoded data to be decoded.
309 * @return the decoded data.
310 */
311 static QCString base64Decode( const QByteArray& in );
312
313 /**
314 * @overload
315 *
316 * Same as the above functions except it accepts
317 * a null terminated string instead an array.
318 *
319 * @param str the base64-encoded string.
320 * @return the decoded string.
321 */
322 static QCString base64Decode( const QCString& str );
323
324 /**
325 * Decodes the given data that was encoded with the base64
326 * algorithm.
327 *
328 * Use this function if you want the result of the decoding
329 * to be placed in another array which cuts down the number
330 * of copy operation that have to be performed in the process.
331 * This is also the preferred method for decoding an encoded
332 * binary data.
333 *
334 * NOTE: the output array is first reset and then resized
335 * appropriately before use, hence, all data stored in the
336 * output array will be lost.
337 *
338 * @param in the encoded data to be decoded.
339 * @param out the container for the decoded data.
340 */
341 static void base64Decode( const QByteArray& in, QByteArray& out );
342
343
344private:
345 KCodecs();
346
347private:
348 static const char UUEncMap[64];
349 static const char UUDecMap[128];
350 static const char Base64EncMap[64];
351 static const char Base64DecMap[128];
352 static const char hexChars[16];
353 static const unsigned int maxQPLineLength;
354};
355
356class KMD5Private;
357/**
358 * Provides an easy to use C++ implementation of RSA's
359 * MD5 algorithm.
360 *
361 * The default constructor is designed to provide much the same
362 * functionality as the most commonly used C-implementation, while
363 * the other three constructors are meant to further simplify the
364 * process of obtaining a digest by calculating the result in a
365 * single step.
366 *
367 * KMD5 is state-based, that means you can add new contents with
368 * update() as long as you didn't request the digest value yet.
369 * After the digest value was requested, the object is "finalized"
370 * and you have to call reset() to be able to do another calculation
371 * with it. The reason for this behaviour is that upon requesting
372 * the message digest KMD5 has to pad the received contents up to a
373 * 64 byte boundary to calculate its value. After this operation it
374 * is not possible to resume consuming data.
375 *
376 * @sect Usage:
377 *
378 * A common usage of this class:
379 *
380 * <PRE>
381 * const char* test1;
382 * KMD5::Digest rawResult;
383 *
384 * test1 = "This is a simple test.";
385 * KMD5 context (test1);
386 * cout << "Hex Digest output: " << context.hexDigest().data() << endl;
387 * </PRE>
388 *
389 * To cut down on the unnecessary overhead of creating multiple KMD5
390 * objects, you can simply invoke @ref reset() to reuse the same object
391 * in making another calculation:
392 *
393 * <PRE>
394 * context.reset ();
395 * context.update ("TWO");
396 * context.update ("THREE");
397 * cout << "Hex Digest output: " << context.hexDigest().data() << endl;
398 * </PRE>
399 *
400 * @short An adapted C++ implementation of RSA Data Securities MD5 algorithm.
401 * @author Dirk Mueller <mueller@kde.org>, Dawit Alemayehu <adawit@kde.org>
402 */
403
404class KMD5
405{
406public:
407
408 typedef unsigned char Digest[16];
409
410 KMD5();
411
412 /**
413 * Constructor that updates the digest for the given string.
414 *
415 * @param in C string or binary data
416 * @param len if negative, calculates the length by using
417 * strlen on the first parameter, otherwise
418 * it trusts the given length (does not stop on NUL byte).
419 */
420 KMD5(const char* in, int len = -1);
421
422 /**
423 * @overload
424 *
425 * Same as above except it accepts a QByteArray as its argument.
426 */
427 KMD5(const QByteArray& a );
428
429 /**
430 * @overload
431 *
432 * Same as above except it accepts a QByteArray as its argument.
433 */
434 KMD5(const QCString& a );
435
436 /**
437 * Updates the message to be digested. Be sure to add all data
438 * before you read the digest. After reading the digest, you
439 * can <b>not</b> add more data!
440 *
441 * @param in message to be added to digest
442 * @param len the length of the given message.
443 */
444 void update(const char* in, int len = -1) { update(reinterpret_cast<const unsigned char*>(in), len); }
445
446 /**
447 * @overload
448 */
449 void update(const unsigned char* in, int len = -1);
450
451 /**
452 * @overload
453 *
454 * @param in message to be added to the digest (QByteArray).
455 */
456 void update(const QByteArray& in );
457
458 /**
459 * @overload
460 *
461 * @param in message to be added to the digest (QByteArray).
462 */
463 void update(const QCString& in );
464
465 /**
466 * @overload
467 *
468 * reads the data from an I/O device, i.e. from a file (QFile).
469 *
470 * NOTE that the file must be open for reading.
471 *
472 * @param file a pointer to FILE as returned by calls like f{d,re}open
473 *
474 * @returns false if an error occured during reading.
475 */
476 bool update(QIODevice& file);
477
478 /**
479 * Calling this function will reset the calculated message digest.
480 * Use this method to perform another message digest calculation
481 * without recreating the KMD5 object.
482 */
483 void reset();
484
485 /**
486 * @return the raw representation of the digest
487 */
488 const Digest& rawDigest ();
489
490 /**
491 * Fills the given array with the binary representation of the
492 * message digest.
493 *
494 * Use this method if you do not want to worry about making
495 * copy of the digest once you obtain it.
496 *
497 * @param bin an array of 16 characters ( char[16] )
498 */
499 void rawDigest( KMD5::Digest& bin );
500
501 /**
502 * Returns the value of the calculated message digest in
503 * a hexadecimal representation.
504 */
505 QCString hexDigest ();
506
507 /**
508 * @overload
509 */
510 void hexDigest(QCString&);
511
512 /**
513 * Returns the value of the calculated message digest in
514 * a base64-encoded representation.
515 */
516 QCString base64Digest ();
517
518 /**
519 * returns true if the calculated digest for the given
520 * message matches the given one.
521 */
522 bool verify( const KMD5::Digest& digest);
523
524 /**
525 * @overload
526 */
527 bool verify(const QCString&);
528
529protected:
530 /**
531 * Performs the real update work. Note
532 * that length is implied to be 64.
533 */
534 void transform( const unsigned char buffer[64] );
535
536 /**
537 * finalizes the digest
538 */
539 void finalize();
540
541private:
542 KMD5(const KMD5& u);
543 KMD5& operator=(const KMD5& md);
544
545 void init();
546 void encode( unsigned char* output, Q_UINT32 *in, Q_UINT32 len );
547 void decode( Q_UINT32 *output, const unsigned char* in, Q_UINT32 len );
548
549 Q_UINT32 rotate_left( Q_UINT32 x, Q_UINT32 n );
550 Q_UINT32 F( Q_UINT32 x, Q_UINT32 y, Q_UINT32 z );
551 Q_UINT32 G( Q_UINT32 x, Q_UINT32 y, Q_UINT32 z );
552 Q_UINT32 H( Q_UINT32 x, Q_UINT32 y, Q_UINT32 z );
553 Q_UINT32 I( Q_UINT32 x, Q_UINT32 y, Q_UINT32 z );
554 void FF( Q_UINT32& a, Q_UINT32 b, Q_UINT32 c, Q_UINT32 d, Q_UINT32 x,
555 Q_UINT32 s, Q_UINT32 ac );
556 void GG( Q_UINT32& a, Q_UINT32 b, Q_UINT32 c, Q_UINT32 d, Q_UINT32 x,
557 Q_UINT32 s, Q_UINT32 ac );
558 void HH( Q_UINT32& a, Q_UINT32 b, Q_UINT32 c, Q_UINT32 d, Q_UINT32 x,
559 Q_UINT32 s, Q_UINT32 ac );
560 void II( Q_UINT32& a, Q_UINT32 b, Q_UINT32 c, Q_UINT32 d, Q_UINT32 x,
561 Q_UINT32 s, Q_UINT32 ac );
562
563private:
564 Q_UINT32 m_state[4];
565 Q_UINT32 m_count[2];
566 Q_UINT8 m_buffer[64];
567 Digest m_digest;
568 bool m_finalized;
569
570 KMD5Private* d;
571};
572#endif
diff --git a/microkde/kdecore/ksharedptr.h b/microkde/kdecore/ksharedptr.h
new file mode 100644
index 0000000..545058a
--- a/dev/null
+++ b/microkde/kdecore/ksharedptr.h
@@ -0,0 +1,171 @@
1/* This file is part of the KDE libraries
2 Copyright (c) 1999 Waldo Bastian <bastian@kde.org>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License version 2 as published by the Free Software Foundation.
7
8 This library is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 Library General Public License for more details.
12
13 You should have received a copy of the GNU Library General Public License
14 along with this library; see the file COPYING.LIB. If not, write to
15 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16 Boston, MA 02111-1307, USA.
17*/
18#ifndef KSharedPTR_H
19#define KSharedPTR_H
20
21/**
22 * Reference counting for shared objects. If you derive your object
23 * from this class, then you may use it in conjunction with
24 * @ref KSharedPtr to control the lifetime of your object.
25 *
26 * Specifically, all classes that derive from KShared have an internal
27 * counter keeping track of how many other objects have a reference to
28 * their object. If used with @ref KSharedPtr, then your object will
29 * not be deleted until all references to the object have been
30 * released.
31 *
32 * You should probably not ever use any of the methods in this class
33 * directly -- let the @ref KSharedPtr take care of that. Just derive
34 * your class from KShared and forget about it.
35 *
36 * @author Waldo Bastian <bastian@kde.org>
37 * @version $Id$
38 */
39class KShared {
40public:
41 /**
42 * Standard constructor. This will initialize the reference count
43 * on this object to 0.
44 */
45 KShared() : count(0) { }
46
47 /**
48 * Copy constructor. This will @em not actually copy the objects
49 * but it will initialize the reference count on this object to 0.
50 */
51 KShared( const KShared & ) : count(0) { }
52
53 /**
54 * Overloaded assignment operator.
55 */
56 KShared &operator=(const KShared & ) { return *this; }
57
58 /**
59 * Increases the reference count by one.
60 */
61 void _KShared_ref() const { count++; }
62
63 /**
64 * Releases a reference (decreases the reference count by one). If
65 * the count goes to 0, this object will delete itself.
66 */
67 void _KShared_unref() const { if (!--count) delete this; }
68
69 /**
70 * Return the current number of references held.
71 *
72 * @return Number of references
73 */
74 int _KShared_count() const { return count; }
75
76protected:
77 virtual ~KShared() { }
78private:
79 mutable int count;
80};
81
82/**
83 * Can be used to control the lifetime of an object that has derived
84 * @ref KShared. As long a someone holds a KSharedPtr on some @ref KShared
85 * object it won't become deleted but is deleted once its reference
86 * count is 0. This struct emulates C++ pointers perfectly. So just
87 * use it like a simple C++ pointer.
88 *
89 * KShared and KSharedPtr are preferred over QShared / QSharedPtr
90 * since they are more safe.
91 *
92 * @author Waldo Bastian <bastian@kde.org>
93 * @version $Id$
94 */
95template< class T >
96struct KSharedPtr
97{
98public:
99/**
100 * Creates a null pointer.
101 */
102 KSharedPtr()
103 : ptr(0) { }
104 /**
105 * Creates a new pointer.
106 * @param the pointer
107 */
108 KSharedPtr( T* t )
109 : ptr(t) { if ( ptr ) ptr->_KShared_ref(); }
110
111 /**
112 * Copies a pointer.
113 * @param the pointer to copy
114 */
115 KSharedPtr( const KSharedPtr& p )
116 : ptr(p.ptr) { if ( ptr ) ptr->_KShared_ref(); }
117
118 /**
119 * Unreferences the object that this pointer points to. If it was
120 * the last reference, the object will be deleted.
121 */
122 ~KSharedPtr() { if ( ptr ) ptr->_KShared_unref(); }
123
124 KSharedPtr<T>& operator= ( const KSharedPtr<T>& p ) {
125 if ( ptr == p.ptr ) return *this;
126 if ( ptr ) ptr->_KShared_unref();
127 ptr = p.ptr;
128 if ( ptr ) ptr->_KShared_ref();
129 return *this;
130 }
131 KSharedPtr<T>& operator= ( T* p ) {
132 if ( ptr == p ) return *this;
133 if ( ptr ) ptr->_KShared_unref();
134 ptr = p;
135 if ( ptr ) ptr->_KShared_ref();
136 return *this;
137 }
138 bool operator== ( const KSharedPtr<T>& p ) const { return ( ptr == p.ptr ); }
139 bool operator!= ( const KSharedPtr<T>& p ) const { return ( ptr != p.ptr ); }
140 bool operator== ( const T* p ) const { return ( ptr == p ); }
141 bool operator!= ( const T* p ) const { return ( ptr != p ); }
142 bool operator!() const { return ( ptr == 0 ); }
143 operator T*() const { return ptr; }
144
145 /**
146 * Returns the pointer.
147 * @return the pointer
148 */
149 T* data() { return ptr; }
150
151 /**
152 * Returns the pointer.
153 * @return the pointer
154 */
155 const T* data() const { return ptr; }
156
157 const T& operator*() const { return *ptr; }
158 T& operator*() { return *ptr; }
159 const T* operator->() const { return ptr; }
160 T* operator->() { return ptr; }
161
162 /**
163 * Returns the number of references.
164 * @return the number of references
165 */
166 int count() const { return ptr->_KShared_count(); } // for debugging purposes
167private:
168 T* ptr;
169};
170
171#endif
diff --git a/microkde/kdecore/kshell.cpp b/microkde/kdecore/kshell.cpp
new file mode 100644
index 0000000..efc007a
--- a/dev/null
+++ b/microkde/kdecore/kshell.cpp
@@ -0,0 +1,386 @@
1/*
2 This file is part of the KDE libraries
3
4 Copyright (c) 2003 Oswald Buddenhagen <ossi@kde.org>
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
15
16 You should have received a copy of the GNU Library General Public License
17 along with this library; see the file COPYING.LIB. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.
20*/
21
22#include <kshell.h>
23
24#include <qfile.h>
25#include <qdir.h>
26
27#include <stdlib.h>
28#ifndef _WIN32_
29#include <pwd.h>
30#endif
31//US #include <sys/types.h>
32
33/*US
34static int fromHex( QChar c )
35{
36 if (c >= '0' && c <= '9')
37 return c - '0';
38 else if (c >= 'A' && c <= 'F')
39 return c - 'A' + 10;
40 else if (c >= 'a' && c <= 'f')
41 return c - 'a' + 10;
42 return -1;
43}
44
45inline static bool isQuoteMeta( uint c )
46{
47#if 0 // it's not worth it, especially after seeing gcc's asm output ...
48 static const uchar iqm[] = {
49 0x00, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00,
50 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00
51 }; // \'"$
52
53 return (c < sizeof(iqm) * 8) && (iqm[c / 8] & (1 << (c & 7)));
54#else
55 return c == '\\' || c == '\'' || c == '"' || c == '$';
56#endif
57}
58
59inline static bool isMeta( uint c )
60{
61 static const uchar iqm[] = {
62 0x00, 0x00, 0x00, 0x00, 0xdc, 0x07, 0x00, 0xd8,
63 0x00, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x38
64 }; // \'"$`<>|;&(){}*?#
65
66 return (c < sizeof(iqm) * 8) && (iqm[c / 8] & (1 << (c & 7)));
67}
68
69QStringList KShell::splitArgs( const QString &args, int flags, int *err )
70{
71 QStringList ret;
72 bool firstword = flags & AbortOnMeta;
73
74 for (uint pos = 0; ; ) {
75 QChar c;
76 do {
77 if (pos >= args.length())
78 goto okret;
79 c = args.unicode()[pos++];
80 } while (c.isSpace());
81 QString cret;
82 if ((flags & TildeExpand) && c == '~') {
83 uint opos = pos;
84 for (; ; pos++) {
85 if (pos >= args.length())
86 break;
87 c = args.unicode()[pos];
88 if (c == '/' || c.isSpace())
89 break;
90 if (isQuoteMeta( c )) {
91 pos = opos;
92 c = '~';
93 goto notilde;
94 }
95 if ((flags & AbortOnMeta) && isMeta( c ))
96 goto metaerr;
97 }
98 QString ccret = homeDir( QConstString( args.unicode() + opos, pos - opos ).string() );
99 if (ccret.isEmpty()) {
100 pos = opos;
101 c = '~';
102 goto notilde;
103 }
104 if (pos >= args.length()) {
105 ret += ccret;
106 goto okret;
107 }
108 pos++;
109 if (c.isSpace()) {
110 ret += ccret;
111 firstword = false;
112 continue;
113 }
114 cret = ccret;
115 }
116 // before the notilde label, as a tilde does not match anyway
117 if (firstword) {
118 if (c == '_' || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) {
119 uint pos2 = pos;
120 QChar cc;
121 do
122 cc = args[pos2++];
123 while (cc == '_' || (cc >= 'A' && cc <= 'Z') ||
124 (cc >= 'a' && cc <= 'z') || (cc >= '0' && cc <= '9'));
125 if (cc == '=')
126 goto metaerr;
127 }
128 }
129 notilde:
130 do {
131 if (c == '\'') {
132 uint spos = pos;
133 do {
134 if (pos >= args.length())
135 goto quoteerr;
136 c = args.unicode()[pos++];
137 } while (c != '\'');
138 cret += QConstString( args.unicode() + spos, pos - spos - 1 ).string();
139 } else if (c == '"') {
140 for (;;) {
141 if (pos >= args.length())
142 goto quoteerr;
143 c = args.unicode()[pos++];
144 if (c == '"')
145 break;
146 if (c == '\\') {
147 if (pos >= args.length())
148 goto quoteerr;
149 c = args.unicode()[pos++];
150 if (c != '"' && c != '\\' &&
151 !((flags & AbortOnMeta) && (c == '$' || c == '`')))
152 cret += '\\';
153 } else if ((flags & AbortOnMeta) && (c == '$' || c == '`'))
154 goto metaerr;
155 cret += c;
156 }
157 } else if (c == '$' && args[pos] == '\'') {
158 pos++;
159 for (;;) {
160 if (pos >= args.length())
161 goto quoteerr;
162 c = args.unicode()[pos++];
163 if (c == '\'')
164 break;
165 if (c == '\\') {
166 if (pos >= args.length())
167 goto quoteerr;
168 c = args.unicode()[pos++];
169 switch (c) {
170 case 'a': cret += '\a'; break;
171 case 'b': cret += '\b'; break;
172 case 'e': cret += '\033'; break;
173 case 'f': cret += '\f'; break;
174 case 'n': cret += '\n'; break;
175 case 'r': cret += '\r'; break;
176 case 't': cret += '\t'; break;
177 case '\\': cret += '\\'; break;
178 case '\'': cret += '\''; break;
179 case 'c': cret += args[pos++] & 31; break;
180 case 'x':
181 {
182 int hv = fromHex( args[pos] );
183 if (hv < 0) {
184 cret += "\\x";
185 } else {
186 int hhv = fromHex( args[++pos] );
187 if (hhv > 0) {
188 hv = hv * 16 + hhv;
189 pos++;
190 }
191 cret += QChar( hv );
192 }
193 break;
194 }
195 default:
196 if (c >= '0' && c <= '7') {
197 int hv = c - '0';
198 for (int i = 0; i < 2; i++) {
199 c = args[pos];
200 if (c < '0' || c > '7')
201 break;
202 hv = hv * 8 + (c - '0');
203 pos++;
204 }
205 cret += QChar( hv );
206 } else {
207 cret += '\\';
208 cret += c;
209 }
210 break;
211 }
212 } else
213 cret += c;
214 }
215 } else {
216 if (c == '\\') {
217 if (pos >= args.length())
218 goto quoteerr;
219 c = args.unicode()[pos++];
220 if (!c.isSpace() &&
221 !((flags & AbortOnMeta) ? isMeta( c ) : isQuoteMeta( c )))
222 cret += '\\';
223 } else if ((flags & AbortOnMeta) && isMeta( c ))
224 goto metaerr;
225 cret += c;
226 }
227 if (pos >= args.length())
228 break;
229 c = args.unicode()[pos++];
230 } while (!c.isSpace());
231 ret += cret;
232 firstword = false;
233 }
234
235 okret:
236 if (err)
237 *err = NoError;
238 return ret;
239
240 quoteerr:
241 if (err)
242 *err = BadQuoting;
243 return QStringList();
244
245 metaerr:
246 if (err)
247 *err = FoundMeta;
248 return QStringList();
249}
250
251inline static bool isSpecial( uint c )
252{
253 static const uchar iqm[] = {
254 0xff, 0xff, 0xff, 0xff, 0xdd, 0x07, 0x00, 0xd8,
255 0x00, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x38
256 }; // 0-32 \'"$`<>|;&(){}*?#
257
258 return (c < sizeof(iqm) * 8) && (iqm[c / 8] & (1 << (c & 7)));
259}
260
261QString KShell::joinArgs( const QStringList &args )
262{
263 QChar q( '\'' );
264 QString ret;
265 for (QStringList::ConstIterator it = args.begin(); it != args.end(); ++it) {
266 if (!ret.isEmpty())
267 ret += ' ';
268 if (!(*it).length())
269 ret.append( q ).append( q );
270 else {
271 for (uint i = 0; i < (*it).length(); i++)
272 if (isSpecial((*it).unicode()[i])) {
273 QString tmp(*it);
274 tmp.replace( q, "'\\''" );
275 ret += q;
276 tmp += q;
277 ret += tmp;
278 goto ex;
279 }
280 ret += *it;
281 ex: ;
282 }
283 }
284 return ret;
285}
286
287QString KShell::joinArgs( const char * const *args, int nargs )
288{
289 if (!args)
290 return QString::null; // well, QString::empty, in fact. qt sucks ;)
291 QChar q( '\'' );
292 QString ret;
293 for (const char * const *argp = args; nargs && *argp; argp++, nargs--) {
294 if (!ret.isEmpty())
295 ret += ' ';
296 if (!**argp)
297 ret.append( q ).append( q );
298 else {
299 QString tmp( QFile::decodeName( *argp ) );
300 for (uint i = 0; i < tmp.length(); i++)
301 if (isSpecial(tmp.unicode()[i])) {
302 tmp.replace( q, "'\\''" );
303 ret += q;
304 tmp += q;
305 ret += tmp;
306 goto ex;
307 }
308 ret += tmp;
309 ex: ;
310 }
311 }
312 return ret;
313}
314
315QString KShell::joinArgsDQ( const QStringList &args )
316{
317 QChar q( '\'' ), sp( ' ' ), bs( '\\' );
318 QString ret;
319 for (QStringList::ConstIterator it = args.begin(); it != args.end(); ++it) {
320 if (!ret.isEmpty())
321 ret += sp;
322 if (!(*it).length())
323 ret.append( q ).append( q );
324 else {
325 for (uint i = 0; i < (*it).length(); i++)
326 if (isSpecial((*it).unicode()[i])) {
327 ret.append( '$' ).append( q );
328 for (uint pos = 0; pos < (*it).length(); pos++) {
329 int c = (*it).unicode()[pos];
330 if (c < 32) {
331 ret += bs;
332 switch (c) {
333 case '\a': ret += 'a'; break;
334 case '\b': ret += 'b'; break;
335 case '\033': ret += 'e'; break;
336 case '\f': ret += 'f'; break;
337 case '\n': ret += 'n'; break;
338 case '\r': ret += 'r'; break;
339 case '\t': ret += 't'; break;
340 case '\034': ret += 'c'; ret += '|'; break;
341 default: ret += 'c'; ret += c + '@'; break;
342 }
343 } else {
344 if (c == '\'' || c == '\\')
345 ret += bs;
346 ret += c;
347 }
348 }
349 ret.append( q );
350 goto ex;
351 }
352 ret += *it;
353 ex: ;
354 }
355 }
356 return ret;
357}
358*/
359
360QString KShell::tildeExpand( const QString &fname )
361{
362 if (fname[0] == '~') {
363 int pos = fname.find( '/' );
364 if (pos < 0)
365 return homeDir( QConstString( (QChar*)(fname.unicode() + 1), fname.length() - 1 ).string() );
366 QString ret = homeDir( QConstString( (QChar*)(fname.unicode() + 1), pos - 1 ).string() );
367 if (!ret.isNull())
368 ret += QConstString( (QChar*)(fname.unicode() + pos), fname.length() - pos ).string();
369 return ret;
370 }
371 return fname;
372}
373
374QString KShell::homeDir( const QString &user )
375{
376#ifdef _WIN32_
377 return QDir::homeDirPath();
378#else
379 if (user.isEmpty())
380 return QFile::decodeName( getenv( "HOME" ) );
381 struct passwd *pw = getpwnam( QFile::encodeName( user ).data() );
382 if (!pw)
383 return QString::null;
384 return QFile::decodeName( pw->pw_dir );
385#endif
386}
diff --git a/microkde/kdecore/kshell.h b/microkde/kdecore/kshell.h
new file mode 100644
index 0000000..35d8217
--- a/dev/null
+++ b/microkde/kdecore/kshell.h
@@ -0,0 +1,143 @@
1/*
2 This file is part of the KDE libraries
3
4 Copyright (c) 2003 Oswald Buddenhagen <ossi@kde.org>
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
15
16 You should have received a copy of the GNU Library General Public License
17 along with this library; see the file COPYING.LIB. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.
20*/
21#ifndef _KSHELL_H
22#define _KSHELL_H
23
24#include <qstring.h>
25#include <qstringlist.h>
26
27/**
28 * Provides some basic POSIX shell and bash functionality.
29 * @see KStringHandler
30 */
31namespace KShell {
32
33 /**
34 * Flags for @ref splitArgs().
35 */
36 enum Options {
37 NoOptions = 0,
38
39 /**
40 * Perform tilde expansion.
41 */
42 TildeExpand = 1,
43
44 /**
45 * Bail out if a non-quoting and not quoted shell meta character is encoutered.
46 * Meta characters are the command separators @p semicolon and @p ampersand,
47 * the redirection symbols @p less-than, @p greater-than and the @p pipe @p symbol,
48 * the grouping symbols opening and closing @p parens and @p braces, the command
49 * substitution symbol @p backquote, the generic substitution symbol @p dollar
50 * (if not followed by an apostrophe), the wildcards @p asterisk and
51 * @p question @p mark, and the comment symbol @p hash @p mark. Additionally,
52 * a variable assignment in the first word is recognized.
53 */
54 AbortOnMeta = 2
55 };
56
57 /**
58 * Status codes from @ref splitArgs()
59 */
60 enum Errors {
61 /**
62 * Success.
63 */
64 NoError = 0,
65
66 /**
67 * Indicates a parsing error, like an unterminated quoted string.
68 */
69 BadQuoting,
70
71 /**
72 * The AbortOnMeta flag was set and a shell meta character
73 * was encoutered.
74 */
75 FoundMeta
76 };
77
78 /**
79 * Splits @p cmd according to POSIX shell word splitting and quoting rules.
80 * Can optionally perform tilde expansion and/or abort if it finds shell
81 * meta characters it cannot process.
82 *
83 * @param cmd the command to split
84 * @param flags operation flags, see @ref Options
85 * @param err if not NULL, a status code will be stored at the pointer
86 * target, see @ref Errors
87 * @return a list of unquoted words or an empty list if an error occured
88 */
89 QStringList splitArgs( const QString &cmd, int flags = 0, int *err = 0 );
90
91 /**
92 * Quotes and joins @p args together according to POSIX shell rules.
93 *
94 * @param args a list of strings to quote and join
95 * @return a command suitable for shell execution
96 */
97 QString joinArgs( const QStringList &args );
98
99 /**
100 * Same as above, but $'' is used instead of '' for the quoting.
101 * The output is suitable for @ref splitArgs(), bash, zsh and possibly
102 * other bourne-compatible shells, but not for plain sh. The advantage
103 * is, that control characters (ASCII less than 32) are escaped into
104 * human-readable strings.
105 *
106 * @param args a list of strings to quote and join
107 * @return a command suitable for shell execution
108 */
109 QString joinArgsDQ( const QStringList &args );
110
111 /**
112 * Quotes and joins @p argv together according to POSIX shell rules.
113 *
114 * @param argv an array of c strings to quote and join.
115 * The strings are expected to be in local-8-bit encoding.
116 * @param argc maximal number of strings in @p argv. if not supplied,
117 * @p argv must be null-terminated.
118 * @return a command suitable for shell execution
119 */
120 QString joinArgs( const char * const *argv, int argc = -1 );
121
122 /**
123 * Performs tilde expansion on @p path. Interprets "~/path" and
124 * "~user/path".
125 *
126 * @param path the path to tilde-expand
127 * @return the expanded path
128 */
129 QString tildeExpand( const QString &path );
130
131 /**
132 * Obtain a @p user's home directory.
133 *
134 * @param user The name of the user whose home dir should be obtained.
135 * An empty string denotes the current user.
136 * @return The user's home directory.
137 */
138 QString homeDir( const QString &user );
139
140}
141
142
143#endif /* _KSHELL_H */
diff --git a/microkde/kdecore/kshortcut.h b/microkde/kdecore/kshortcut.h
new file mode 100644
index 0000000..4813734
--- a/dev/null
+++ b/microkde/kdecore/kshortcut.h
@@ -0,0 +1,846 @@
1/* This file is part of the KDE libraries
2 Copyright (C) 2001,2002 Ellis Whitehead <ellis@kde.org>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA.
18*/
19
20#ifndef __KSHORTCUT_H
21#define __KSHORTCUT_H
22/*US
23#include <qkeysequence.h>
24#include <qstring.h>
25
26class QKeyEvent;
27class KKeyNative;
28*/
29/**
30* A KKey object represents a single key with possible modifiers
31* (Shift, Ctrl, Alt, Win). It can represent both keys which are
32* understood by Qt as well as those which are additionally supported
33* by the underlying system (e.g. X11).
34* @see KKeyNative
35* @see KKeySequence
36* @see KShortcut
37*/
38/*US
39class KKey
40{
41 public:
42*/
43 /**
44 * The number of flags.
45 * @see ModFlag
46 */
47/*US
48 enum { MOD_FLAG_COUNT = 4 };
49 enum { QtWIN = (Qt::ALT << 1) };
50*/
51 /**
52 * Flags to represent the modifiers. You can combine modifiers
53 * by ORing them.
54 */
55/*US
56 enum ModFlag {
57 SHIFT = 0x01,
58 CTRL = 0x02,
59 ALT = 0x04,
60 WIN = 0x08
61 };
62*/
63 /**
64 * Creates a new null KKey.
65 * @see clear()
66 * @see isNull()
67 * @see null()
68 */
69 //USKKey();
70
71 /**
72 * Creates a new key for the given Qt key code.
73 * @param keyQt the qt keycode
74 * @see Qt::Key
75 */
76 //USKKey( int keyQt );
77
78 /**
79 * Creates a new key from the first key code of the given key sequence.
80 * @param keySeq the key sequence that contains the key
81 */
82 //USKKey( const QKeySequence& keySeq );
83
84 /**
85 * Extracts the key from the given key event.
86 * @param keyEvent the key event to get the key from
87 */
88 //USKKey( const QKeyEvent* keyEvent );
89
90 /**
91 * Copy constructor.
92 */
93 //USKKey( const KKey& key );
94
95 /**
96 * Creates a new key from the given description. The form of the description
97 * is "[modifier+[modifier+]]+key", for example "e", "CTRL+q" or
98 * "CTRL+ALT+DEL". Allowed modifiers are "SHIFT", "CTRL", "ALT", "WIN" and
99 * "META". "WIN" and "META" are equivalent. Modifiers are not case-sensitive.
100 * @param key the description of the key
101 * @see KKeyServer::Sym::init()
102 */
103 //USKKey( const QString& key );
104 /**
105 * @internal
106 */
107 //USKKey( uint key, uint mod );
108 //US~KKey();
109
110 // Initialization methods
111 /**
112 * Clears the key. The key is null after calling this function.
113 * @see isNull()
114 */
115 //USvoid clear();
116
117 /**
118 * Initializes the key with the given Qt key code.
119 * @param keyQt the qt keycode
120 * @return true if successful, false otherwise
121 * @see Qt::Key
122 */
123 //USbool init( int keyQt );
124
125 /**
126 * Initializes the key with the first key code of the given key sequence.
127 * @param keySeq the key sequence that contains the key
128 * @return true if successful, false otherwise
129 */
130 //USbool init( const QKeySequence& keySeq );
131
132 /**
133 * Initializes the key by extracting the code from the given key event.
134 * @param keyEvent the key event to get the key from
135 * @return true if successful, false otherwise
136 */
137 //USbool init( const QKeyEvent* keyEvent );
138
139 /**
140 * Copies the given key.
141 * @param key the key to copy
142 * @return true if successful, false otherwise
143 */
144 //USbool init( const KKey& key );
145
146 /**
147 * Initializes the key with the given description. The form of the description
148 * is "[modifier+[modifier+]]+key", for example "e", "CTRL+q" or
149 * "CTRL+ALT+DEL". Allowed modifiers are "SHIFT", "CTRL", "ALT", "WIN" and
150 * "META". "WIN" and "META" are equivalent. Modifiers are not case-sensitive.
151 * @param key the description of the key
152 * @return true if successful, false otherwise
153 * @see KKeyServer::Sym::init()
154 */
155 //USbool init( const QString& );
156
157 /**
158 * @internal
159 */
160 //USbool init( uint key, uint mod );
161
162 /**
163 * Copies the key.
164 */
165 //USKKey& operator =( const KKey& key )
166 //US { init( key ); return *this; }
167
168 // Query methods.
169 /**
170 * Returns true if the key is null (after @ref clear() or empty
171 * constructor).
172 * @return true if the key is null
173 * @see clear()
174 * @see null()
175 */
176 //USbool isNull() const;
177
178 /**
179 * @internal
180 */
181 //USbool isValidQt() const;
182
183 /**
184 * @internal
185 */
186 //USbool isValidNative() const;
187
188 /**
189 * @internal
190 */
191 //USuint sym() const;
192 /**
193 * @internal
194 */
195 //USuint modFlags() const;
196
197 // Comparison Methods
198 /**
199 * Compares this key with the given KKey object. Returns a negative
200 * number if the given KKey is larger, 0 if they are equal and
201 * a positive number this KKey is larger. The returned value
202 * is the difference between the symbol or, if the symbols
203 * are equal, the difference between the encoded modifiers.
204 * @param key the key to compare with this key
205 * @return a negative number if the given KKey is larger, 0 if
206 * they are equal and a positive number this KKey is larger
207 */
208 //USint compare( const KKey& key ) const;
209
210 /**
211 * Compares the symbol and modifiers of both keys.
212 * @see compare()
213 */
214 //USbool operator == ( const KKey& key ) const
215 //US { return compare( key ) == 0; }
216 /**
217 * Compares the symbol and modifiers of both keys.
218 * @see compare()
219 */
220 //USbool operator != ( const KKey& key ) const
221 //US { return compare( key ) != 0; }
222 /**
223 * Compares the symbol and modifiers of both keys.
224 * @see compare()
225 */
226 //USbool operator < ( const KKey& key ) const
227 //US { return compare( key ) < 0; }
228
229 // Conversion methods.
230 /**
231 * Returns the qt key code.
232 * @return the qt key code or 0 if there is no key set.
233 * @see Qt::Key
234 */
235 //USint keyCodeQt() const;
236
237 /**
238 * Returns a human-readable representation of the key in the form
239 * "modifier+key".
240 * @return the string representation of the key
241 */
242 //USQString toString() const;
243
244 /**
245 * @internal
246 */
247//US QString toStringInternal() const;
248
249 // Operation methods
250 /**
251 * @internal
252 */
253 //USvoid simplify();
254
255 /**
256 * Returns a null key.
257 * @return the null key
258 * @see isNull()
259 * @see clear()
260 */
261 //USstatic KKey& null();
262
263 /**
264 * Returns a user-readable representation of the given modifiers.
265 * @param f the modifiers to convert
266 * @return the string representation of the modifiers
267 */
268 //USstatic QString modFlagLabel( ModFlag f );
269
270//US private:
271 /*
272 * Under X11, m_key will hold an X11 key symbol.
273 * For Qt/Embedded, it will hold the Qt key code.
274 */
275 /**
276 * Returns the native key symbol value key. Under X11, this is the X
277 * keycode. Under Qt/Embedded, this is the Qt keycode.
278 * @see /usr/include/X11/keysymdef.h
279 * @see qnamespace.h
280 */
281 //USuint m_sym;
282 /**
283 * m_mod holds the
284 */
285 //USuint m_mod;
286
287//US private:
288 //USfriend class KKeyNative;
289//US};
290
291/**
292* A KKeySequence object holds a sequence of up to 4 keys.
293* Ex: Ctrl+X,I
294* @see KKey
295* @see KShortcut
296*/
297
298//USclass KKeySequence
299//US{
300//US public:
301 /// Defines the maximum length of the key sequence
302//US enum { MAX_KEYS = 4 };
303
304 /**
305 * Create a new null key sequence.
306 * @see isNull()
307 * @see null()
308 * @see clear()
309 */
310 //USKKeySequence();
311
312 /**
313 * Copies the given qt key sequence.
314 * @param keySeq the qt key sequence to copy
315 */
316 //USKKeySequence( const QKeySequence& keySeq );
317
318 /**
319 * Create a new key sequence that only contains the given key.
320 * @param key the key to add
321 */
322 //USKKeySequence( const KKey& key );
323
324 /**
325 * Create a new key sequence that only contains the given key.
326 * @param key the key to add
327 */
328 //USKKeySequence( const KKeyNative& key );
329
330 /**
331 * Copies the given key sequence.
332 * @param keySeq the key sequence to copy
333 */
334 //USKKeySequence( const KKeySequence& keySeq );
335
336 /**
337 * Creates a new key sequence that contains the given key sequence.
338 * The description consists of comma-separated keys as
339 * required by @ref KKey::KKey(const QString&).
340 * @param keySeq the description of the key
341 * @see KKeyServer::Sym::init()
342 * @see KKey::KKey(const QString&)
343 */
344 //USKKeySequence( const QString& keySeq );
345
346 //US~KKeySequence();
347
348 /**
349 * Clears the key sequence. The key sequence is null after calling this
350 * function.
351 * @see isNull()
352 */
353 //USvoid clear();
354
355 /**
356 * Copies the given qt key sequence over this key sequence.
357 * @param keySeq the qt key sequence to copy
358 * @return true if successful, false otherwise
359 */
360 //USbool init( const QKeySequence& keySeq );
361
362 /**
363 * Initializes the key sequence to only contain the given key.
364 * @param key the key to set
365 * @return true if successful, false otherwise
366 */
367 //USbool init( const KKey& key );
368
369 /**
370 * Initializes the key sequence to only contain the given key.
371 * @param key the key to set
372 * @return true if successful, false otherwise
373 */
374 //USbool init( const KKeyNative& key );
375
376 /**
377 * Copies the given key sequence over this key sequence.
378 * @param keySeq the key sequence to copy
379 * @return true if successful, false otherwise
380 */
381 //USbool init( const KKeySequence& keySeq );
382
383 /**
384 * Initializes this key sequence to contain the given key sequence.
385 * The description consists of comma-separated keys as
386 * required by @ref KKey::KKey(const QString&).
387 * @param key the description of the key
388 * @return true if successful, false otherwise
389 * @see KKeyServer::Sym::init()
390 * @see KKey::KKey(const QString&)
391 */
392 //USbool init( const QString& key );
393
394 /**
395 * Copy the given key sequence into this sequence.
396 */
397 //USKKeySequence& operator =( const KKeySequence& seq )
398 //US { init( seq ); return *this; }
399
400 /**
401 * Returns the number of key strokes of this sequence.
402 * @return the number of key strokes
403 * @see MAX_KEYS
404 */
405 //USuint count() const;
406
407 /**
408 * Return the @p i'th key of this sequence, or a null key if there
409 * are less then i keys.
410 * @param i the key to retrieve
411 * @return the @p i'th key, or @ref KKey::null() if there are less
412 * than i keys
413 * @see MAX_KEYS
414 */
415 //USconst KKey& key( uint i ) const;
416
417 /**
418 * @internal
419 */
420 //USbool isTriggerOnRelease() const;
421
422 /**
423 * Sets the @p i'th key of the sequence. You can not introduce gaps
424 * in a sequence, so you must use an @p i <= @ref count(). Also note that
425 * the maximum length of a key sequence is @ref MAX_KEYS.
426 * @param i the position of the new key (<= @ref count(), <= @ref MAX_KEYS)
427 * @param key the key to set
428 * @return true if successful, false otherwise
429 */
430 //USbool setKey( uint i, const KKey& key );
431
432 /**
433 * @internal
434 */
435 //USvoid setTriggerOnRelease( bool );
436
437 /**
438 * Returns true if the key sequence is null (after @ref clear() or empty
439 * constructor).
440 * @return true if the key sequence is null
441 * @see clear()
442 * @see null()
443 */
444//US bool isNull() const;
445
446 /**
447 * Returns true if this key sequence begins with the given sequence.
448 * @param keySeq the key sequence to search
449 * @return true if this key sequence begins with the given sequence
450 */
451 //USbool startsWith( const KKeySequence& keySeq ) const;
452
453 /**
454 * Compares this object with the given key sequence. Returns a negative
455 * number if the given KKeySequence is larger, 0 if they are equal and
456 * a positive number this KKeySequence is larger. Key sequences are
457 * compared by comparing the individual keys, starting from the beginning
458 * until an unequal key has been found. If a sequence contains more
459 * keys, it is considered larger.
460 * @param keySeq the key sequence to compare to
461 * @return a negative number if the given KKeySequence is larger, 0 if
462 * they are equal and a positive number this KKeySequence is larger
463 * @see KKey::sequence
464 */
465 //USint compare( const KKeySequence& keySeq ) const;
466
467 /**
468 * Compares the keys of both sequences.
469 * @see compare()
470 */
471 //USbool operator == ( const KKeySequence& seq ) const
472 //US { return compare( seq ) == 0; }
473
474 /**
475 * Compares the keys of both sequences.
476 * @see compare()
477 */
478 //USbool operator != ( const KKeySequence& seq ) const
479 //US { return compare( seq ) != 0; }
480
481 /**
482 * Compares the keys of both sequences.
483 * @see compare()
484 */
485 //USbool operator < ( const KKeySequence& seq ) const
486 //US { return compare( seq ) < 0; }
487 // TODO: consider adding Qt::SequenceMatch matches(...) methods for QKeySequence equivalence
488
489 /**
490 * Converts this key sequence to a QKeySequence.
491 * @return the QKeySequence
492 */
493 //USQKeySequence qt() const;
494
495 /**
496 * Returns the qt key code of the first key.
497 * @return the qt key code of the first key
498 * @see Qt::Key
499 * @see KKey::keyCodeQt()
500 */
501 //USint keyCodeQt() const;
502
503 /**
504 * Returns the key sequence as a number of key presses as
505 * returned by @ref KKey::toString(), seperated by commas.
506 * @return the string represenation of this key sequence
507 * @see KKey::toString()
508 */
509 //USQString toString() const;
510
511 /**
512 * @internal
513 */
514//US QString toStringInternal() const;
515
516 /**
517 * Returns a null key sequence.
518 * @return the null key sequence
519 * @see isNull()
520 * @see clear()
521 */
522 //USstatic KKeySequence& null();
523
524//US protected:
525 //USuchar m_nKeys;
526 //USuchar m_bTriggerOnRelease;
527 // BCI: m_rgvar should be renamed to m_rgkey for KDE 4.0
528 //USKKey m_rgvar[MAX_KEYS];
529
530//US private:
531 //USclass KKeySequencePrivate* d;
532 //USfriend class KKeyNative;
533//US};
534
535/**
536* The KShortcut class is used to represent a keyboard shortcut to an action.
537* A shortcut is normally a single key with modifiers, such as Ctrl+V.
538* A KShortcut object may also contain an alternate key which will also
539* activate the action it's associated to, as long as no other actions have
540* defined that key as their primary key. Ex: Ctrl+V;Shift+Insert.
541*/
542
543class KShortcut
544{
545 public:
546 /**
547 * The maximum number of key sequences that can be contained in
548 * a KShortcut.
549 */
550 enum { MAX_SEQUENCES = 2 };
551
552 /**
553 * Creates a new null shortcut.
554 * @see null()
555 * @see isNull()
556 * @see clear()
557 */
558 KShortcut() {}
559
560 /**
561 * Creates a new shortcut with the given Qt key code
562 * as the only key sequence.
563 * @param keyQt the qt keycode
564 * @see Qt::Key
565 */
566 KShortcut( int keyQt ) {}
567
568 /**
569 * Creates a new shortcut that contains only the given qt key
570 * sequence.
571 * @param keySeq the qt key sequence to add
572 */
573 //USKShortcut( const QKeySequence& keySeq ) {}
574
575 /**
576 * Creates a new shortcut that contains only the given key
577 * in its only sequence.
578 * @param key the key to add
579 */
580 //USKShortcut( const KKey& key );
581
582 /**
583 * Creates a new shortcut that contains only the given key
584 * sequence.
585 * @param keySeq the key sequence to add
586 */
587 //USKShortcut( const KKeySequence& keySeq );
588
589 /**
590 * Copies the given shortcut.
591 * @param shortcut the shortcut to add
592 */
593 //USKShortcut( const KShortcut& shortcut );
594
595 /**
596 * Creates a new key sequence that contains the given key sequence.
597 * The description consists of semicolon-separated keys as
598 * used in @ref KKeySequence::KKeySequence(const QString&).
599 * @param shortcut the description of the key
600 * @see KKeySequence::KKeySequence(const QString&)
601 */
602 KShortcut( const char* shortcut ) {}
603
604 /**
605 * Creates a new key sequence that contains the given key sequence.
606 * The description consists of semicolon-separated keys as
607 * used in @ref KKeySequence::KKeySequence(const QString&).
608 * @param shortcut the description of the key
609 * @see KKeySequence::KKeySequence(const QString&)
610 */
611 KShortcut( const QString& shortcut ) {}
612 ~KShortcut() {}
613
614 /**
615 * Clears the shortcut. The shortcut is null after calling this
616 * function.
617 * @see isNull()
618 */
619 //USvoid clear();
620
621 /**
622 * Initializes the shortcut with the given Qt key code
623 * as the only key sequence.
624 * @param keyQt the qt keycode
625 * @see Qt::Key
626 */
627 //USbool init( int keyQt );
628
629 /**
630 * Initializes the shortcut with the given qt key sequence.
631 * @param keySeq the qt key sequence to add
632 */
633 //USbool init( const QKeySequence& keySeq );
634
635 /**
636 * Initializes the shortcut with the given key as its only sequence.
637 * @param key the key to add
638 */
639 //USbool init( const KKey& key );
640
641 /**
642 * Initializes the shortcut with the given qt key sequence.
643 * @param keySeq the qt key sequence to add
644 */
645 //USbool init( const KKeySequence& keySeq );
646
647 /**
648 * Copies the given shortcut.
649 * @param shortcut the shortcut to add
650 */
651 //USbool init( const KShortcut& shortcut );
652
653 /**
654 * Initializes the key sequence with the given key sequence.
655 * The description consists of semicolon-separated keys as
656 * used in @ref KKeySequence::KKeySequence(const QString&).
657 * @param shortcut the description of the key
658 * @see KKeySequence::KKeySequence(const QString&)
659 */
660 //USbool init( const QString& shortcut );
661
662 /**
663 * Copies the given shortcut over this shortcut.
664 */
665 //USKShortcut& operator =( const KShortcut& cut )
666 //US { init( cut ); return *this; }
667
668 /**
669 * Returns the number of sequences that are in this
670 * shortcut.
671 * @return the number of sequences
672 * @ref MAX_SEQUENCES
673 */
674 //USuint count() const;
675
676 /**
677 * Returns the @p i'th key sequence of this shortcut.
678 * @param i the number of the key sequence to retrieve
679 * @return the @p i'th sequence or @ref KKeySequence::null() if
680 * there are less than @p i key sequences
681 * @ref MAX_SEQUENCES
682 */
683 //USconst KKeySequence& seq( uint i ) const;
684
685 /**
686 * Returns the key code of the first key sequence, or
687 * null if there is no first key sequence.
688 * @return the key code of the first sequence's first key
689 * @see Qt::Key
690 * @see KKeySequence::keyCodeQt()
691 */
692 //USint keyCodeQt() const;
693
694 /**
695 * Returns true if the shortcut is null (after @ref clear() or empty
696 * constructor).
697 * @return true if the shortcut is null
698 * @see clear()
699 * @see null()
700 */
701 bool isNull() const { return true; }
702
703 /**
704 * Compares this object with the given shortcut. Returns a negative
705 * number if the given shortcut is larger, 0 if they are equal and
706 * a positive number this shortcut is larger. Shortcuts are
707 * compared by comparing the individual key sequences, starting from the
708 * beginning until an unequal key sequences has been found. If a shortcut
709 * contains more key sequences, it is considered larger.
710 * @param shortcut the shortcut to compare to
711 * @return a negative number if the given KShortcut is larger, 0 if
712 * they are equal and a positive number this KShortcut is larger
713 * @see KKey::compare()
714 * @see KKeyShortcut::compare()
715 */
716 //USint compare( const KShortcut& shortcut ) const;
717
718 /**
719 * Compares the sequences of both shortcuts.
720 * @see compare()
721 */
722 //USbool operator == ( const KShortcut& cut ) const
723 //US { return compare( cut ) == 0; }
724
725 /**
726 * Compares the sequences of both shortcuts.
727 * @see compare()
728 */
729 //USbool operator != ( const KShortcut& cut ) const
730 //US { return compare( cut ) != 0; }
731
732 /**
733 * Compares the sequences of both shortcuts.
734 * @see compare()
735 */
736 //USbool operator < ( const KShortcut& cut ) const
737 //US { return compare( cut ) < 0; }
738
739 /**
740 * Checks whether this shortcut contains a sequence that starts
741 * with the given key.
742 * @param key the key to check
743 * @return true if a key sequence starts with the key
744 */
745 //USbool contains( const KKey& key ) const;
746
747 /**
748 * Checks whether this shortcut contains a sequence that starts
749 * with the given key.
750 * @param key the key to check
751 * @return true if a key sequence starts with the key
752 */
753 //USbool contains( const KKeyNative& key ) const;
754
755 /**
756 * Checks whether this shortcut contains the given sequence.
757 * @param keySeq the key sequence to check
758 * @return true if the shortcut has the given key sequence
759 */
760 //USbool contains( const KKeySequence& keySeq ) const;
761
762 /**
763 * Sets the @p i'th key sequence of the shortcut. You can not introduce
764 * gaps in the list of sequences, so you must use an @i <= @ref count().
765 * Also note that the maximum number of key sequences is @ref MAX_SEQUENCES.
766 * @param i the position of the new key sequence(<= @ref count(),
767 * <= @ref MAX_SEQUENCES)
768 * @param keySeq the key sequence to set
769 * @return true if successful, false otherwise
770 */
771 //USbool setSeq( uint i, const KKeySequence& keySeq );
772
773 /**
774 * Appends the given key sequence.
775 * @param keySeq the key sequence to add
776 * @return true if successful, false otherwise
777 * @see setSeq()
778 * @see MAX_SEQUENCES
779 */
780 //USbool append( const KKeySequence& keySeq );
781
782 /**
783 * Appends the given key
784 * @param spec the key to add
785 * @return true if successful, false otherwise
786 * @see setSeq()
787 * @see MAX_SEQUENCES
788 * @since 3.2
789 */
790 //USbool append( const KKey& spec );
791
792 /**
793 * Appends the sequences from the given shortcut.
794 * @param cut the shortcut to append
795 * @return true if successful, false otherwise
796 * @see MAX_SEQUENCES
797 * @since 3.2
798 */
799 //USbool append( const KShortcut& cut );
800
801 /**
802 * Converts this shortcut to a key sequence. The first key sequence
803 * will be taken.
804 */
805 //USoperator QKeySequence () const;
806
807 /**
808 * Returns a description of the shortcut as semicolon-separated
809 * ket sequences, as returned by @ref KKeySequence::toString().
810 * @return the string represenation of this shortcut
811 * @see KKey::toString()
812 * @see KKeySequence::toString()
813 */
814 //USQString toString() const;
815
816 /**
817 * @internal
818 */
819 QString toStringInternal( const KShortcut* pcutDefault = 0 ) const
820 {
821 return "EMPTY IMPL.";
822 }
823
824 /**
825 * Returns a null shortcut.
826 * @return the null shortcut
827 * @see isNull()
828 * @see clear()
829 */
830 //USstatic KShortcut& null();
831
832//US protected:
833 //USuint m_nSeqs;
834 //USKKeySequence m_rgseq[MAX_SEQUENCES];
835
836//US private:
837 //USclass KShortcutPrivate* d;
838 //USfriend class KKeyNative;
839
840//US#ifndef KDE_NO_COMPAT
841//US public:
842 //USoperator int () const { return keyCodeQt(); }
843//US#endif
844};
845
846#endif // __KSHORTCUT_H
diff --git a/microkde/kdecore/kstandarddirs.cpp b/microkde/kdecore/kstandarddirs.cpp
new file mode 100644
index 0000000..5abe05c
--- a/dev/null
+++ b/microkde/kdecore/kstandarddirs.cpp
@@ -0,0 +1,1620 @@
1/* This file is part of the KDE libraries
2 Copyright (C) 1999 Sirtaj Singh Kang <taj@kde.org>
3 Copyright (C) 1999 Stephan Kulow <coolo@kde.org>
4 Copyright (C) 1999 Waldo Bastian <bastian@kde.org>
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License version 2 as published by the Free Software Foundation.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21/*
22 * Author: Stephan Kulow <coolo@kde.org> and Sirtaj Singh Kang <taj@kde.org>
23 * Version:$Id$
24 * Generated:Thu Mar 5 16:05:28 EST 1998
25 */
26
27//US #include "config.h"
28
29#include <stdlib.h>
30#include <assert.h>
31//US#include <errno.h>
32//US #ifdef HAVE_SYS_STAT_H
33//US #include <sys/stat.h>
34//US #endif
35//US#include <sys/types.h>
36//US#include <dirent.h>
37//US#include <pwd.h>
38
39#include <qregexp.h>
40#include <qasciidict.h>
41#include <qdict.h>
42#include <qdir.h>
43#include <qfileinfo.h>
44#include <qstring.h>
45#include <qstringlist.h>
46
47#include "kstandarddirs.h"
48#include "kconfig.h"
49#include "kdebug.h"
50//US #include "kinstance.h"
51#include "kshell.h"
52//US#include <sys/param.h>
53//US#include <unistd.h>
54
55//US
56QString KStandardDirs::mAppDir = QString::null;
57
58
59template class QDict<QStringList>;
60
61#if 0
62#include <qtextedit.h>
63void ddd( QString op )
64{
65 static QTextEdit * dot = 0;
66 if ( ! dot )
67 dot = new QTextEdit();
68
69 dot->show();
70
71 dot->append( op );
72
73}
74#endif
75class KStandardDirs::KStandardDirsPrivate
76{
77public:
78 KStandardDirsPrivate()
79 : restrictionsActive(false),
80 dataRestrictionActive(false)
81 { }
82
83 bool restrictionsActive;
84 bool dataRestrictionActive;
85 QAsciiDict<bool> restrictions;
86 QStringList xdgdata_prefixes;
87 QStringList xdgconf_prefixes;
88};
89
90static const char* const types[] = {"html", "icon", "apps", "sound",
91 "data", "locale", "services", "mime",
92 "servicetypes", "config", "exe",
93 "wallpaper", "lib", "pixmap", "templates",
94 "module", "qtplugins",
95 "xdgdata-apps", "xdgdata-dirs", "xdgconf-menu", 0 };
96
97static int tokenize( QStringList& token, const QString& str,
98 const QString& delim );
99
100KStandardDirs::KStandardDirs( ) : addedCustoms(false)
101{
102 d = new KStandardDirsPrivate;
103 dircache.setAutoDelete(true);
104 relatives.setAutoDelete(true);
105 absolutes.setAutoDelete(true);
106 savelocations.setAutoDelete(true);
107 addKDEDefaults();
108}
109
110KStandardDirs::~KStandardDirs()
111{
112 delete d;
113}
114
115bool KStandardDirs::isRestrictedResource(const char *type, const QString& relPath) const
116{
117 if (!d || !d->restrictionsActive)
118 return false;
119
120 if (d->restrictions[type])
121 return true;
122
123 if (strcmp(type, "data")==0)
124 {
125 applyDataRestrictions(relPath);
126 if (d->dataRestrictionActive)
127 {
128 d->dataRestrictionActive = false;
129 return true;
130 }
131 }
132 return false;
133}
134
135void KStandardDirs::applyDataRestrictions(const QString &relPath) const
136{
137 QString key;
138 int i = relPath.find('/');
139 if (i != -1)
140 key = "data_"+relPath.left(i);
141 else
142 key = "data_"+relPath;
143
144 if (d && d->restrictions[key.latin1()])
145 d->dataRestrictionActive = true;
146}
147
148
149QStringList KStandardDirs::allTypes() const
150{
151 QStringList list;
152 for (int i = 0; types[i] != 0; ++i)
153 list.append(QString::fromLatin1(types[i]));
154 return list;
155}
156
157void KStandardDirs::addPrefix( const QString& _dir )
158{
159 if (_dir.isNull())
160 return;
161
162 QString dir = _dir;
163 if (dir.at(dir.length() - 1) != '/')
164 dir += '/';
165
166 if (!prefixes.contains(dir)) {
167 prefixes.append(dir);
168 dircache.clear();
169 }
170}
171
172void KStandardDirs::addXdgConfigPrefix( const QString& _dir )
173{
174 if (_dir.isNull())
175 return;
176
177 QString dir = _dir;
178 if (dir.at(dir.length() - 1) != '/')
179 dir += '/';
180
181 if (!d->xdgconf_prefixes.contains(dir)) {
182 d->xdgconf_prefixes.append(dir);
183 dircache.clear();
184 }
185}
186
187void KStandardDirs::addXdgDataPrefix( const QString& _dir )
188{
189 if (_dir.isNull())
190 return;
191
192 QString dir = _dir;
193 if (dir.at(dir.length() - 1) != '/')
194 dir += '/';
195
196 if (!d->xdgdata_prefixes.contains(dir)) {
197 d->xdgdata_prefixes.append(dir);
198 dircache.clear();
199 }
200}
201
202
203QString KStandardDirs::kfsstnd_prefixes()
204{
205 return prefixes.join(":");
206}
207
208bool KStandardDirs::addResourceType( const char *type,
209 const QString& relativename )
210{
211 if (relativename.isNull())
212 return false;
213
214 QStringList *rels = relatives.find(type);
215 if (!rels) {
216 rels = new QStringList();
217 relatives.insert(type, rels);
218 }
219 QString copy = relativename;
220 if (copy.at(copy.length() - 1) != '/')
221 copy += '/';
222 if (!rels->contains(copy)) {
223 rels->prepend(copy);
224 dircache.remove(type); // clean the cache
225 return true;
226 }
227 return false;
228}
229
230bool KStandardDirs::addResourceDir( const char *type,
231 const QString& absdir)
232{
233 QStringList *paths = absolutes.find(type);
234 if (!paths) {
235 paths = new QStringList();
236 absolutes.insert(type, paths);
237 }
238 QString copy = absdir;
239 if (copy.at(copy.length() - 1) != '/')
240 copy += '/';
241
242 if (!paths->contains(copy)) {
243 paths->append(copy);
244 dircache.remove(type); // clean the cache
245 return true;
246 }
247 return false;
248}
249
250QString KStandardDirs::findResource( const char *type,
251 const QString& filename ) const
252{
253 if (filename.at(0) == '/')
254 return filename; // absolute dirs are absolute dirs, right? :-/
255
256#if 0
257kdDebug() << "Find resource: " << type << endl;
258for (QStringList::ConstIterator pit = prefixes.begin();
259 pit != prefixes.end();
260 pit++)
261{
262 kdDebug() << "Prefix: " << *pit << endl;
263}
264#endif
265
266 QString dir = findResourceDir(type, filename);
267 if (dir.isNull())
268 return dir;
269 else return dir + filename;
270}
271/*US
272static Q_UINT32 updateHash(const QString &file, Q_UINT32 hash)
273{
274 QCString cFile = QFile::encodeName(file);
275//US struct stat buff;
276//US if ((access(cFile, R_OK) == 0) &&
277//US (stat( cFile, &buff ) == 0) &&
278//US (S_ISREG( buff.st_mode )))
279 QFileInfo pathfnInfo(cFile);
280 if (( pathfnInfo.isReadable() == true ) &&
281 ( pathfnInfo.isFile()) )
282 {
283//US hash = hash + (Q_UINT32) buff.st_ctime;
284 hash = hash + (Q_UINT32) pathfnInfo.lastModified();
285 }
286 return hash;
287}
288*/
289/*US
290Q_UINT32 KStandardDirs::calcResourceHash( const char *type,
291 const QString& filename, bool deep) const
292{
293 Q_UINT32 hash = 0;
294
295 if (filename.at(0) == '/')
296 {
297 // absolute dirs are absolute dirs, right? :-/
298 return updateHash(filename, hash);
299 }
300 if (d && d->restrictionsActive && (strcmp(type, "data")==0))
301 applyDataRestrictions(filename);
302 QStringList candidates = resourceDirs(type);
303 QString fullPath;
304
305 for (QStringList::ConstIterator it = candidates.begin();
306 it != candidates.end(); it++)
307 {
308 hash = updateHash(*it + filename, hash);
309 if (!deep && hash)
310 return hash;
311 }
312 return hash;
313}
314*/
315
316QStringList KStandardDirs::findDirs( const char *type,
317 const QString& reldir ) const
318{
319 QStringList list;
320
321 checkConfig();
322
323 if (d && d->restrictionsActive && (strcmp(type, "data")==0))
324 applyDataRestrictions(reldir);
325 QStringList candidates = resourceDirs(type);
326 QDir testdir;
327
328 for (QStringList::ConstIterator it = candidates.begin();
329 it != candidates.end(); it++) {
330 testdir.setPath(*it + reldir);
331 if (testdir.exists())
332 list.append(testdir.absPath() + '/');
333 }
334
335 return list;
336}
337
338QString KStandardDirs::findResourceDir( const char *type,
339 const QString& filename) const
340{
341#ifndef NDEBUG
342 if (filename.isEmpty()) {
343 kdWarning() << "filename for type " << type << " in KStandardDirs::findResourceDir is not supposed to be empty!!" << endl;
344 return QString::null;
345 }
346#endif
347
348 if (d && d->restrictionsActive && (strcmp(type, "data")==0))
349 applyDataRestrictions(filename);
350 QStringList candidates = resourceDirs(type);
351 QString fullPath;
352
353 for (QStringList::ConstIterator it = candidates.begin();
354 it != candidates.end(); it++)
355 if (exists(*it + filename))
356 return *it;
357
358#ifndef NDEBUG
359 if(false && type != "locale")
360 kdDebug() << "KStdDirs::findResDir(): can't find \"" << filename << "\" in type \"" << type << "\"." << endl;
361#endif
362
363 return QString::null;
364}
365
366bool KStandardDirs::exists(const QString &fullPath)
367{
368//US struct stat buff;
369 QFileInfo fullPathInfo(QFile::encodeName(fullPath));
370
371//US if (access(QFile::encodeName(fullPath), R_OK) == 0 && fullPathInfo.isReadable())
372 if (fullPathInfo.isReadable())
373 {
374 if (fullPath.at(fullPath.length() - 1) != '/') {
375 //US if (S_ISREG( buff.st_mode ))
376 if (fullPathInfo.isFile())
377 return true;
378 }
379 else {
380 //US if (S_ISDIR( buff.st_mode ))
381 if (fullPathInfo.isDir())
382 return true;
383 }
384 }
385 return false;
386}
387
388static void lookupDirectory(const QString& path, const QString &relPart,
389 const QRegExp &regexp,
390 QStringList& list,
391 QStringList& relList,
392 bool recursive, bool uniq)
393{
394 QString pattern = regexp.pattern();
395 if (recursive || pattern.contains('?') || pattern.contains('*'))
396 {
397 // We look for a set of files.
398//US DIR *dp = opendir( QFile::encodeName(path));
399 QDir dp(QFile::encodeName(path));
400 if (!dp.exists())
401 return;
402 static int iii = 0;
403 ++iii;
404 if ( iii == 5 )
405 abort();
406 assert(path.at(path.length() - 1) == '/');
407
408//US struct dirent *ep;
409//US struct stat buff;
410
411 QString _dot(".");
412 QString _dotdot("..");
413
414//US while( ( ep = readdir( dp ) ) != 0L )
415 QStringList direntries = dp.entryList();
416 QStringList::Iterator it = direntries.begin();
417
418 while ( it != list.end() ) // for each file...
419 {
420
421//US QString fn( QFile::decodeName(ep->d_name));
422 QString fn = (*it); // dp.entryList already decodes
423 it++;
424 if ( fn.isNull() )
425 break;
426
427 if (fn == _dot || fn == _dotdot || fn.at(fn.length() - 1).latin1() == '~' )
428 continue;
429
430/*US
431 if (!recursive && !regexp.exactMatch(fn))
432 continue; // No match
433*/
434//US this should do the same:
435 int pos = regexp.match(fn);
436 if (!recursive && !pos == 0)
437 continue; // No match
438
439 QString pathfn = path + fn;
440/*US
441 if ( stat( QFile::encodeName(pathfn), &buff ) != 0 ) {
442 kdDebug() << "Error stat'ing " << pathfn << " : " << perror << endl;
443 continue; // Couldn't stat (e.g. no read permissions)
444 }
445
446 if ( recursive )
447 {
448 if ( S_ISDIR( buff.st_mode )) {
449 lookupDirectory(pathfn + '/', relPart + fn + '/', regexp, list, relList, recursive, uniq);
450 }
451*/
452//US replacement:
453 QFileInfo pathfnInfo(QFile::encodeName(pathfn));
454 if ( pathfnInfo.isReadable() == false )
455 {
456//US kdDebug() << "Error stat'ing " << pathfn << " : " << perror << endl;
457 continue; // Couldn't stat (e.g. no read permissions)
458 }
459
460 if ( recursive )
461 {
462 if ( pathfnInfo.isDir()) {
463 lookupDirectory(pathfn + '/', relPart + fn + '/', regexp, list, relList, recursive, uniq);
464 }
465
466
467/*US
468 if (!regexp.exactMatch(fn))
469 continue; // No match
470*/
471//US this should do the same:
472 pos = regexp.match(fn);
473 if (!pos == 0)
474 continue; // No match
475 }
476
477//US if ( S_ISREG( buff.st_mode))
478 if ( pathfnInfo.isFile())
479 {
480 if (!uniq || !relList.contains(relPart + fn))
481 {
482 list.append( pathfn );
483 relList.append( relPart + fn );
484 }
485 }
486 }
487//US closedir( dp );
488 }
489 else
490 {
491 // We look for a single file.
492 QString fn = pattern;
493 QString pathfn = path + fn;
494//US struct stat buff;
495 QFileInfo pathfnInfo(QFile::encodeName(pathfn));
496
497
498//US if ( stat( QFile::encodeName(pathfn), &buff ) != 0 )
499 if ( pathfnInfo.isReadable() == false )
500 return; // File not found
501
502//US if ( S_ISREG( buff.st_mode))
503 if ( pathfnInfo.isFile())
504 {
505 if (!uniq || !relList.contains(relPart + fn))
506 {
507 list.append( pathfn );
508 relList.append( relPart + fn );
509 }
510 }
511 }
512}
513
514static void lookupPrefix(const QString& prefix, const QString& relpath,
515 const QString& relPart,
516 const QRegExp &regexp,
517 QStringList& list,
518 QStringList& relList,
519 bool recursive, bool uniq)
520{
521 if (relpath.isNull()) {
522 lookupDirectory(prefix, relPart, regexp, list,
523 relList, recursive, uniq);
524 return;
525 }
526 QString path;
527 QString rest;
528
529 if (relpath.length())
530 {
531 int slash = relpath.find('/');
532 if (slash < 0)
533 rest = relpath.left(relpath.length() - 1);
534 else {
535 path = relpath.left(slash);
536 rest = relpath.mid(slash + 1);
537 }
538 }
539 assert(prefix.at(prefix.length() - 1) == '/');
540
541//US struct stat buff;
542
543 if (path.contains('*') || path.contains('?')) {
544 QRegExp pathExp(path, true, true);
545 //USDIR *dp = opendir( QFile::encodeName(prefix) );
546 QDir dp(QFile::encodeName(prefix));
547
548 //USif (!dp)
549 if (!dp.exists())
550 {
551 return;
552 }
553
554 //USstruct dirent *ep;
555
556 QString _dot(".");
557 QString _dotdot("..");
558
559 //USwhile( ( ep = readdir( dp ) ) != 0L )
560 QStringList direntries = dp.entryList();
561 QStringList::Iterator it = direntries.begin();
562
563 while ( it != list.end() ) // for each file...
564 {
565//US QString fn( QFile::decodeName(ep->d_name));
566 QString fn = (*it); // dp.entryList() already encodes the strings
567 it++;
568
569 if (fn == _dot || fn == _dotdot || fn.at(fn.length() - 1) == '~')
570 continue;
571
572#ifdef DESKTOP_VERSION
573
574 if (pathExp.search(fn) == -1)
575 continue; // No match
576
577#else
578//US this should do the same:
579 if (pathExp.find(fn, 0) == -1)
580 continue; // No match
581#endif
582 QString rfn = relPart+fn;
583 fn = prefix + fn;
584//US if ( stat( QFile::encodeName(fn), &buff ) != 0 )
585 QFileInfo fnInfo(QFile::encodeName(fn));
586 if ( fnInfo.isReadable() == false )
587 {
588//US kdDebug() << "Error statting " << fn << " : " << perror << endl;
589 continue; // Couldn't stat (e.g. no permissions)
590 }
591 //US if ( S_ISDIR( buff.st_mode ))
592 if ( fnInfo.isDir() )
593
594 lookupPrefix(fn + '/', rest, rfn + '/', regexp, list, relList, recursive, uniq);
595 }
596
597 //USclosedir( dp );
598 } else {
599 // Don't stat, if the dir doesn't exist we will find out
600 // when we try to open it.
601 lookupPrefix(prefix + path + '/', rest,
602 relPart + path + '/', regexp, list,
603 relList, recursive, uniq);
604 }
605}
606
607QStringList
608KStandardDirs::findAllResources( const char *type,
609 const QString& filter,
610 bool recursive,
611 bool uniq,
612 QStringList &relList) const
613{
614 QStringList list;
615 if (filter.at(0) == '/') // absolute paths we return
616 {
617 list.append( filter);
618 return list;
619 }
620
621 QString filterPath;
622 QString filterFile;
623
624 if (filter.length())
625 {
626 int slash = filter.findRev('/');
627 if (slash < 0)
628 filterFile = filter;
629 else {
630 filterPath = filter.left(slash + 1);
631 filterFile = filter.mid(slash + 1);
632 }
633 }
634 checkConfig();
635
636 if (d && d->restrictionsActive && (strcmp(type, "data")==0))
637 applyDataRestrictions(filter);
638 QStringList candidates = resourceDirs(type);
639 if (filterFile.isEmpty())
640 filterFile = "*";
641
642 QRegExp regExp(filterFile, true, true);
643 for (QStringList::ConstIterator it = candidates.begin();
644 it != candidates.end(); it++)
645 {
646 lookupPrefix(*it, filterPath, "", regExp, list,
647 relList, recursive, uniq);
648 }
649 return list;
650}
651
652QStringList
653KStandardDirs::findAllResources( const char *type,
654 const QString& filter,
655 bool recursive,
656 bool uniq) const
657{
658 QStringList relList;
659 return findAllResources(type, filter, recursive, uniq, relList);
660}
661
662QString
663KStandardDirs::realPath(const QString &dirname)
664{
665#ifdef _WIN32_
666 return dirname;
667#else
668//US char realpath_buffer[MAXPATHLEN + 1];
669//US memset(realpath_buffer, 0, MAXPATHLEN + 1);
670 char realpath_buffer[250 + 1];
671 memset(realpath_buffer, 0, 250 + 1);
672
673 /* If the path contains symlinks, get the real name */
674 if (realpath( QFile::encodeName(dirname).data(), realpath_buffer) != 0) {
675 // succes, use result from realpath
676 int len = strlen(realpath_buffer);
677 realpath_buffer[len] = '/';
678 realpath_buffer[len+1] = 0;
679 return QFile::decodeName(realpath_buffer);
680 }
681
682 return dirname;
683#endif
684}
685/*US
686void KStandardDirs::createSpecialResource(const char *type)
687{
688 char hostname[256];
689 hostname[0] = 0;
690 gethostname(hostname, 255);
691 QString dir = QString("%1%2-%3").arg(localkdedir()).arg(type).arg(hostname);
692 char link[1024];
693 link[1023] = 0;
694 int result = readlink(QFile::encodeName(dir).data(), link, 1023);
695 if ((result == -1) && (errno == ENOENT))
696 {
697 QString srv = findExe(QString::fromLatin1("lnusertemp"), KDEDIR+QString::fromLatin1("/bin"));
698 if (srv.isEmpty())
699 srv = findExe(QString::fromLatin1("lnusertemp"));
700 if (!srv.isEmpty())
701 {
702 system(QFile::encodeName(srv)+" "+type);
703 result = readlink(QFile::encodeName(dir).data(), link, 1023);
704 }
705 }
706 if (result > 0)
707 {
708 link[result] = 0;
709 if (link[0] == '/')
710 dir = QFile::decodeName(link);
711 else
712 dir = QDir::cleanDirPath(dir+QFile::decodeName(link));
713 }
714 addResourceDir(type, dir+'/');
715}
716*/
717
718QStringList KStandardDirs::resourceDirs(const char *type) const
719{
720 QStringList *candidates = dircache.find(type);
721
722 if (!candidates) { // filling cache
723/*US
724 if (strcmp(type, "socket") == 0)
725 const_cast<KStandardDirs *>(this)->createSpecialResource(type);
726 else if (strcmp(type, "tmp") == 0)
727 const_cast<KStandardDirs *>(this)->createSpecialResource(type);
728 else if (strcmp(type, "cache") == 0)
729 const_cast<KStandardDirs *>(this)->createSpecialResource(type);
730*/
731 QDir testdir;
732
733 candidates = new QStringList();
734 QStringList *dirs;
735
736 bool restrictionActive = false;
737 if (d && d->restrictionsActive)
738 {
739 if (d->dataRestrictionActive)
740 restrictionActive = true;
741 else if (d->restrictions["all"])
742 restrictionActive = true;
743 else if (d->restrictions[type])
744 restrictionActive = true;
745 d->dataRestrictionActive = false; // Reset
746 }
747
748 dirs = relatives.find(type);
749 if (dirs)
750 {
751 bool local = true;
752 const QStringList *prefixList = 0;
753 if (strncmp(type, "xdgdata-", 8) == 0)
754 prefixList = &(d->xdgdata_prefixes);
755 else if (strncmp(type, "xdgconf-", 8) == 0)
756 prefixList = &(d->xdgconf_prefixes);
757 else
758 prefixList = &prefixes;
759
760 for (QStringList::ConstIterator pit = prefixList->begin();
761 pit != prefixList->end();
762 pit++)
763 {
764 for (QStringList::ConstIterator it = dirs->begin();
765 it != dirs->end(); ++it) {
766 QString path = realPath(*pit + *it);
767 testdir.setPath(path);
768 if (local && restrictionActive)
769 continue;
770 if ((local || testdir.exists()) && !candidates->contains(path))
771 candidates->append(path);
772 }
773 local = false;
774 }
775 }
776 dirs = absolutes.find(type);
777 if (dirs)
778 for (QStringList::ConstIterator it = dirs->begin();
779 it != dirs->end(); ++it)
780 {
781 testdir.setPath(*it);
782 if (testdir.exists())
783 {
784 QString filename = realPath(*it);
785 if (!candidates->contains(filename))
786 candidates->append(filename);
787 }
788 }
789 dircache.insert(type, candidates);
790 }
791
792#if 0
793 kdDebug() << "found dirs for resource " << type << ":" << endl;
794 for (QStringList::ConstIterator pit = candidates->begin();
795 pit != candidates->end();
796 pit++)
797 {
798 fprintf(stderr, "%s\n", (*pit).latin1());
799 }
800#endif
801
802
803 return *candidates;
804}
805
806/*US
807QString KStandardDirs::findExe( const QString& appname,
808 const QString& pstr, bool ignore)
809{
810 QFileInfo info;
811
812 // absolute path ?
813 if (appname.startsWith(QString::fromLatin1("/")))
814 {
815 info.setFile( appname );
816 if( info.exists() && ( ignore || info.isExecutable() )
817 && info.isFile() ) {
818 return appname;
819 }
820 return QString::null;
821 }
822
823//US QString p = QString("%1/%2").arg(__KDE_BINDIR).arg(appname);
824 QString p = QString("%1/%2").arg(appname).arg(appname);
825 qDebug("KStandardDirs::findExe this is probably wrong");
826
827 info.setFile( p );
828 if( info.exists() && ( ignore || info.isExecutable() )
829 && ( info.isFile() || info.isSymLink() ) ) {
830 return p;
831 }
832
833 QStringList tokens;
834 p = pstr;
835
836 if( p.isNull() ) {
837 p = getenv( "PATH" );
838 }
839
840 tokenize( tokens, p, ":\b" );
841
842 // split path using : or \b as delimiters
843 for( unsigned i = 0; i < tokens.count(); i++ ) {
844 p = tokens[ i ];
845
846 if ( p[ 0 ] == '~' )
847 {
848 int len = p.find( '/' );
849 if ( len == -1 )
850 len = p.length();
851 if ( len == 1 )
852 p.replace( 0, 1, QDir::homeDirPath() );
853 else
854 {
855 QString user = p.mid( 1, len - 1 );
856 struct passwd *dir = getpwnam( user.local8Bit().data() );
857 if ( dir && strlen( dir->pw_dir ) )
858 p.replace( 0, len, QString::fromLocal8Bit( dir->pw_dir ) );
859 }
860 }
861
862 p += "/";
863 p += appname;
864
865 // Check for executable in this tokenized path
866 info.setFile( p );
867
868 if( info.exists() && ( ignore || info.isExecutable() )
869 && ( info.isFile() || info.isSymLink() ) ) {
870 return p;
871 }
872 }
873
874 // If we reach here, the executable wasn't found.
875 // So return empty string.
876
877 return QString::null;
878}
879
880int KStandardDirs::findAllExe( QStringList& list, const QString& appname,
881 const QString& pstr, bool ignore )
882{
883 QString p = pstr;
884 QFileInfo info;
885 QStringList tokens;
886
887 if( p.isNull() ) {
888 p = getenv( "PATH" );
889 }
890
891 list.clear();
892 tokenize( tokens, p, ":\b" );
893
894 for ( unsigned i = 0; i < tokens.count(); i++ ) {
895 p = tokens[ i ];
896 p += "/";
897 p += appname;
898
899 info.setFile( p );
900
901 if( info.exists() && (ignore || info.isExecutable())
902 && info.isFile() ) {
903 list.append( p );
904 }
905
906 }
907
908 return list.count();
909}
910*/
911
912static int tokenize( QStringList& tokens, const QString& str,
913 const QString& delim )
914{
915 int len = str.length();
916 QString token = "";
917
918 for( int index = 0; index < len; index++)
919 {
920 if ( delim.find( str[ index ] ) >= 0 )
921 {
922 tokens.append( token );
923 token = "";
924 }
925 else
926 {
927 token += str[ index ];
928 }
929 }
930 if ( token.length() > 0 )
931 {
932 tokens.append( token );
933 }
934
935 return tokens.count();
936}
937
938QString KStandardDirs::kde_default(const char *type) {
939 if (!strcmp(type, "data"))
940 return "apps/";
941 if (!strcmp(type, "html"))
942 return "share/doc/HTML/";
943 if (!strcmp(type, "icon"))
944 return "share/icons/";
945 if (!strcmp(type, "config"))
946 return "config/";
947 if (!strcmp(type, "pixmap"))
948 return "share/pixmaps/";
949 if (!strcmp(type, "apps"))
950 return "share/applnk/";
951 if (!strcmp(type, "sound"))
952 return "share/sounds/";
953 if (!strcmp(type, "locale"))
954 return "share/locale/";
955 if (!strcmp(type, "services"))
956 return "share/services/";
957 if (!strcmp(type, "servicetypes"))
958 return "share/servicetypes/";
959 if (!strcmp(type, "mime"))
960 return "share/mimelnk/";
961 if (!strcmp(type, "cgi"))
962 return "cgi-bin/";
963 if (!strcmp(type, "wallpaper"))
964 return "share/wallpapers/";
965 if (!strcmp(type, "templates"))
966 return "share/templates/";
967 if (!strcmp(type, "exe"))
968 return "bin/";
969 if (!strcmp(type, "lib"))
970 return "lib/";
971 if (!strcmp(type, "module"))
972 return "lib/kde3/";
973 if (!strcmp(type, "qtplugins"))
974 return "lib/kde3/plugins";
975 if (!strcmp(type, "xdgdata-apps"))
976 return "applications/";
977 if (!strcmp(type, "xdgdata-dirs"))
978 return "desktop-directories/";
979 if (!strcmp(type, "xdgconf-menu"))
980 return "menus/";
981 qFatal("unknown resource type %s", type);
982 return QString::null;
983}
984
985QString KStandardDirs::saveLocation(const char *type,
986 const QString& suffix,
987 bool create) const
988{
989 //qDebug("KStandardDirs::saveLocation called %s %s", type,suffix.latin1() );
990 //return "";
991 checkConfig();
992
993 QString *pPath = savelocations.find(type);
994 if (!pPath)
995 {
996 QStringList *dirs = relatives.find(type);
997 if (!dirs && (
998 (strcmp(type, "socket") == 0) ||
999 (strcmp(type, "tmp") == 0) ||
1000 (strcmp(type, "cache") == 0) ))
1001 {
1002 (void) resourceDirs(type); // Generate socket|tmp|cache resource.
1003 dirs = relatives.find(type); // Search again.
1004 }
1005 if (dirs)
1006 {
1007 // Check for existance of typed directory + suffix
1008 if (strncmp(type, "xdgdata-", 8) == 0)
1009 pPath = new QString(realPath(localxdgdatadir() + dirs->last()));
1010 else if (strncmp(type, "xdgconf-", 8) == 0)
1011 pPath = new QString(realPath(localxdgconfdir() + dirs->last()));
1012 else
1013 pPath = new QString(realPath(localkdedir() + dirs->last()));
1014 }
1015 else {
1016 dirs = absolutes.find(type);
1017 if (!dirs)
1018 qFatal("KStandardDirs: The resource type %s is not registered", type);
1019 pPath = new QString(realPath(dirs->last()));
1020 }
1021
1022 savelocations.insert(type, pPath);
1023 }
1024
1025 QString fullPath = *pPath + suffix;
1026//US struct stat st;
1027//US if (stat(QFile::encodeName(fullPath), &st) != 0 || !(S_ISDIR(st.st_mode)))
1028 QFileInfo fullPathInfo(QFile::encodeName(fullPath));
1029 if (fullPathInfo.isReadable() || !fullPathInfo.isDir())
1030
1031
1032 {
1033 if(!create) {
1034#ifndef NDEBUG
1035 qDebug("save location %s doesn't exist", fullPath.latin1());
1036#endif
1037 return fullPath;
1038 }
1039 if(!makeDir(fullPath, 0700)) {
1040 qWarning("failed to create %s", fullPath.latin1());
1041 return fullPath;
1042 }
1043 dircache.remove(type);
1044 }
1045 return fullPath;
1046}
1047
1048QString KStandardDirs::relativeLocation(const char *type, const QString &absPath)
1049{
1050 QString fullPath = absPath;
1051 int i = absPath.findRev('/');
1052 if (i != -1)
1053 {
1054 fullPath = realPath(absPath.left(i+1))+absPath.mid(i+1); // Normalize
1055 }
1056
1057 QStringList candidates = resourceDirs(type);
1058
1059 for (QStringList::ConstIterator it = candidates.begin();
1060 it != candidates.end(); it++)
1061 if (fullPath.startsWith(*it))
1062 {
1063 return fullPath.mid((*it).length());
1064 }
1065
1066 return absPath;
1067}
1068
1069
1070bool KStandardDirs::makeDir(const QString& dir2, int mode)
1071{
1072 QString dir = QDir::convertSeparators( dir2 );
1073#if 0
1074 //LR
1075
1076 // we want an absolute path
1077 if (dir.at(0) != '/')
1078 return false;
1079
1080 QString target = dir;
1081 uint len = target.length();
1082
1083 // append trailing slash if missing
1084 if (dir.at(len - 1) != '/')
1085 target += '/';
1086
1087 QString base("");
1088 uint i = 1;
1089
1090 while( i < len )
1091 {
1092//US struct stat st;
1093 int pos = target.find('/', i);
1094 base += target.mid(i - 1, pos - i + 1);
1095 QCString baseEncoded = QFile::encodeName(base);
1096 // bail out if we encountered a problem
1097//US if (stat(baseEncoded, &st) != 0)
1098 QFileInfo baseEncodedInfo(baseEncoded);
1099 if (!baseEncodedInfo.exists())
1100 {
1101 // Directory does not exist....
1102 // Or maybe a dangling symlink ?
1103//US if (lstat(baseEncoded, &st) == 0)
1104 if (baseEncodedInfo.isSymLink()) {
1105//US (void)unlink(baseEncoded); // try removing
1106 QFile(baseEncoded).remove();
1107 }
1108
1109 //US if ( mkdir(baseEncoded, (mode_t) mode) != 0)
1110 QDir dirObj;
1111 if ( dirObj.mkdir(baseEncoded) != true )
1112 {
1113 //US perror("trying to create local folder");
1114 return false; // Couldn't create it :-(
1115 }
1116 }
1117 i = pos + 1;
1118 }
1119 return true;
1120#endif
1121
1122 // ********************************************
1123 // new code for WIN32
1124 QDir dirObj;
1125
1126
1127 // we want an absolute path
1128#ifndef _WIN32_
1129 if (dir.at(0) != '/')
1130 return false;
1131#endif
1132
1133 QString target = dir;
1134 uint len = target.length();
1135#ifndef _WIN32_
1136 // append trailing slash if missing
1137 if (dir.at(len - 1) != '/')
1138 target += '/';
1139#endif
1140
1141 QString base("");
1142 uint i = 1;
1143
1144 while( i < len )
1145 {
1146//US struct stat st;
1147#ifndef _WIN32_
1148 int pos = target.find('/', i);
1149#else
1150 int pos = target.find('\\', i);
1151#endif
1152 if ( pos < 0 )
1153 return true;
1154 base += target.mid(i - 1, pos - i + 1);
1155 //QMessageBox::information( 0,"cap111", base, 1 );
1156/*US
1157 QCString baseEncoded = QFile::encodeName(base);
1158 // bail out if we encountered a problem
1159 if (stat(baseEncoded, &st) != 0)
1160 {
1161 // Directory does not exist....
1162 // Or maybe a dangling symlink ?
1163 if (lstat(baseEncoded, &st) == 0)
1164 (void)unlink(baseEncoded); // try removing
1165
1166
1167 if ( mkdir(baseEncoded, (mode_t) mode) != 0) {
1168 perror("trying to create local folder");
1169 return false; // Couldn't create it :-(
1170 }
1171 }
1172*/
1173
1174 if (dirObj.exists(base) == false)
1175 {
1176 //qDebug("KStandardDirs::makeDir try to create : %s" , base.latin1());
1177 if (dirObj.mkdir(base) != true)
1178 {
1179 qDebug("KStandardDirs::makeDir could not create: %s" , base.latin1());
1180 return false;
1181 }
1182 }
1183
1184 i = pos + 1;
1185 }
1186 return true;
1187
1188}
1189
1190static QString readEnvPath(const char *env)
1191{
1192#ifdef _WIN32_
1193 return "";
1194#else
1195 QCString c_path = getenv(env);
1196 if (c_path.isEmpty())
1197 return QString::null;
1198 return QFile::decodeName(c_path);
1199#endif
1200}
1201
1202void KStandardDirs::addKDEDefaults()
1203{
1204 //qDebug("ERROR: KStandardDirs::addKDEDefaults() called ");
1205 //return;
1206 QStringList kdedirList;
1207
1208 // begin KDEDIRS
1209 QString kdedirs = readEnvPath("MICROKDEDIRS");
1210 if (!kdedirs.isEmpty())
1211 {
1212 tokenize(kdedirList, kdedirs, ":");
1213 }
1214 else
1215 {
1216 QString kdedir = readEnvPath("MICROKDEDIR");
1217 if (!kdedir.isEmpty())
1218 {
1219 kdedir = KShell::tildeExpand(kdedir);
1220 kdedirList.append(kdedir);
1221 }
1222 }
1223//US kdedirList.append(KDEDIR);
1224
1225#ifdef __KDE_EXECPREFIX
1226 QString execPrefix(__KDE_EXECPREFIX);
1227 if (execPrefix!="NONE")
1228 kdedirList.append(execPrefix);
1229#endif
1230
1231 QString localKdeDir;
1232
1233//US if (getuid())
1234 if (true)
1235 {
1236 localKdeDir = readEnvPath("MICROKDEHOME");
1237 if (!localKdeDir.isEmpty())
1238 {
1239 if (localKdeDir.at(localKdeDir.length()-1) != '/')
1240 localKdeDir += '/';
1241 }
1242 else
1243 {
1244 localKdeDir = QDir::homeDirPath() + "/kdepim/";
1245 }
1246 }
1247 else
1248 {
1249 // We treat root different to prevent root messing up the
1250 // file permissions in the users home directory.
1251 localKdeDir = readEnvPath("MICROKDEROOTHOME");
1252 if (!localKdeDir.isEmpty())
1253 {
1254 if (localKdeDir.at(localKdeDir.length()-1) != '/')
1255 localKdeDir += '/';
1256 }
1257 else
1258 {
1259//US struct passwd *pw = getpwuid(0);
1260//US localKdeDir = QFile::decodeName((pw && pw->pw_dir) ? pw->pw_dir : "/root") + "/.microkde/";
1261 qDebug("KStandardDirs::addKDEDefaults: 1 has to be fixed");
1262 }
1263
1264 }
1265
1266//US localKdeDir = appDir();
1267
1268//US
1269// qDebug("KStandardDirs::addKDEDefaults: localKdeDir=%s", localKdeDir.latin1());
1270 if (localKdeDir != "-/")
1271 {
1272 localKdeDir = KShell::tildeExpand(localKdeDir);
1273 addPrefix(localKdeDir);
1274 }
1275
1276 for (QStringList::ConstIterator it = kdedirList.begin();
1277 it != kdedirList.end(); it++)
1278 {
1279 QString dir = KShell::tildeExpand(*it);
1280 addPrefix(dir);
1281 }
1282 // end KDEDIRS
1283
1284 // begin XDG_CONFIG_XXX
1285 QStringList xdgdirList;
1286 QString xdgdirs = readEnvPath("XDG_CONFIG_DIRS");
1287 if (!xdgdirs.isEmpty())
1288 {
1289 tokenize(xdgdirList, xdgdirs, ":");
1290 }
1291 else
1292 {
1293 xdgdirList.clear();
1294 xdgdirList.append("/etc/xdg");
1295 }
1296
1297 QString localXdgDir = readEnvPath("XDG_CONFIG_HOME");
1298 if (!localXdgDir.isEmpty())
1299 {
1300 if (localXdgDir.at(localXdgDir.length()-1) != '/')
1301 localXdgDir += '/';
1302 }
1303 else
1304 {
1305//US if (getuid())
1306 if (true)
1307 {
1308 localXdgDir = QDir::homeDirPath() + "/.config/";
1309 }
1310 else
1311 {
1312//US struct passwd *pw = getpwuid(0);
1313//US localXdgDir = QFile::decodeName((pw && pw->pw_dir) ? pw->pw_dir : "/root") + "/.config/";
1314 qDebug("KStandardDirs::addKDEDefaults: 2 has to be fixed");
1315 }
1316 }
1317
1318 localXdgDir = KShell::tildeExpand(localXdgDir);
1319 addXdgConfigPrefix(localXdgDir);
1320
1321 for (QStringList::ConstIterator it = xdgdirList.begin();
1322 it != xdgdirList.end(); it++)
1323 {
1324 QString dir = KShell::tildeExpand(*it);
1325 addXdgConfigPrefix(dir);
1326 }
1327 // end XDG_CONFIG_XXX
1328
1329 // begin XDG_DATA_XXX
1330 xdgdirs = readEnvPath("XDG_DATA_DIRS");
1331 if (!xdgdirs.isEmpty())
1332 {
1333 tokenize(xdgdirList, xdgdirs, ":");
1334 }
1335 else
1336 {
1337 xdgdirList.clear();
1338 for (QStringList::ConstIterator it = kdedirList.begin();
1339 it != kdedirList.end(); it++)
1340 {
1341 QString dir = *it;
1342 if (dir.at(dir.length()-1) != '/')
1343 dir += '/';
1344 xdgdirList.append(dir+"share/");
1345 }
1346
1347 xdgdirList.append("/usr/local/share/");
1348 xdgdirList.append("/usr/share/");
1349 }
1350
1351 localXdgDir = readEnvPath("XDG_DATA_HOME");
1352 if (!localXdgDir.isEmpty())
1353 {
1354 if (localXdgDir.at(localXdgDir.length()-1) != '/')
1355 localXdgDir += '/';
1356 }
1357 else
1358 {
1359//US if (getuid())
1360 if (true)
1361 {
1362 localXdgDir = QDir::homeDirPath() + "/.local/share/";
1363 }
1364 else
1365 {
1366//US struct passwd *pw = getpwuid(0);
1367//US localXdgDir = QFile::decodeName((pw && pw->pw_dir) ? pw->pw_dir : "/root") + "/.local/share/";
1368 qDebug("KStandardDirs::addKDEDefaults: 3 has to be fixed");
1369 }
1370 }
1371
1372 localXdgDir = KShell::tildeExpand(localXdgDir);
1373 addXdgDataPrefix(localXdgDir);
1374
1375 for (QStringList::ConstIterator it = xdgdirList.begin();
1376 it != xdgdirList.end(); it++)
1377 {
1378 QString dir = KShell::tildeExpand(*it);
1379
1380 addXdgDataPrefix(dir);
1381 }
1382 // end XDG_DATA_XXX
1383
1384
1385 uint index = 0;
1386 while (types[index] != 0) {
1387 addResourceType(types[index], kde_default(types[index]));
1388 index++;
1389 }
1390
1391 addResourceDir("home", QDir::homeDirPath());
1392}
1393
1394void KStandardDirs::checkConfig() const
1395{
1396/*US
1397 if (!addedCustoms && KGlobal::_instance && KGlobal::_instance->_config)
1398 const_cast<KStandardDirs*>(this)->addCustomized(KGlobal::_instance->_config);
1399*/
1400 if (!addedCustoms && KGlobal::config())
1401 const_cast<KStandardDirs*>(this)->addCustomized(KGlobal::config());
1402}
1403
1404bool KStandardDirs::addCustomized(KConfig *config)
1405{
1406 if (addedCustoms) // there are already customized entries
1407 return false; // we just quite and hope they are the right ones
1408
1409 // save the numbers of config directories. If this changes,
1410 // we will return true to give KConfig a chance to reparse
1411 uint configdirs = resourceDirs("config").count();
1412
1413 // reading the prefixes in
1414 QString oldGroup = config->group();
1415 config->setGroup("Directories");
1416
1417 QStringList list;
1418 QStringList::ConstIterator it;
1419 list = config->readListEntry("prefixes");
1420 for (it = list.begin(); it != list.end(); it++)
1421 addPrefix(*it);
1422
1423 // iterating over all entries in the group Directories
1424 // to find entries that start with dir_$type
1425/*US
1426 QMap<QString, QString> entries = config->entryMap("Directories");
1427
1428 QMap<QString, QString>::ConstIterator it2;
1429 for (it2 = entries.begin(); it2 != entries.end(); it2++)
1430 {
1431 QString key = it2.key();
1432 if (key.left(4) == "dir_") {
1433 // generate directory list, there may be more than 1.
1434 QStringList dirs = QStringList::split(',', *it2);
1435 QStringList::Iterator sIt(dirs.begin());
1436 QString resType = key.mid(4, key.length());
1437 for (; sIt != dirs.end(); ++sIt) {
1438 addResourceDir(resType.latin1(), *sIt);
1439 }
1440 }
1441 }
1442
1443 // Process KIOSK restrictions.
1444 config->setGroup("KDE Resource Restrictions");
1445 entries = config->entryMap("KDE Resource Restrictions");
1446 for (it2 = entries.begin(); it2 != entries.end(); it2++)
1447 {
1448 QString key = it2.key();
1449 if (!config->readBoolEntry(key, true))
1450 {
1451 d->restrictionsActive = true;
1452 d->restrictions.insert(key.latin1(), &d->restrictionsActive); // Anything will do
1453 dircache.remove(key.latin1());
1454 }
1455 }
1456*/
1457 // save it for future calls - that will return
1458 addedCustoms = true;
1459 config->setGroup(oldGroup);
1460
1461 // return true if the number of config dirs changed
1462 return (resourceDirs("config").count() != configdirs);
1463}
1464
1465QString KStandardDirs::localkdedir() const
1466{
1467 // Return the prefix to use for saving
1468 return prefixes.first();
1469}
1470
1471QString KStandardDirs::localxdgdatadir() const
1472{
1473 // Return the prefix to use for saving
1474 return d->xdgdata_prefixes.first();
1475}
1476
1477QString KStandardDirs::localxdgconfdir() const
1478{
1479 // Return the prefix to use for saving
1480 return d->xdgconf_prefixes.first();
1481}
1482
1483void KStandardDirs::setAppDir( const QString &appDir )
1484{
1485 mAppDir = appDir;
1486
1487 if ( mAppDir.right( 1 ) != "/" )
1488 mAppDir += "/";
1489}
1490
1491QString KStandardDirs::appDir()
1492{
1493 return mAppDir;
1494}
1495
1496// just to make code more readable without macros
1497QString locate( const char *type,
1498 const QString& filename/*US , const KInstance* inst*/ )
1499{
1500//US return inst->dirs()->findResource(type, filename);
1501 return KGlobal::dirs()->findResource(type, filename);
1502}
1503
1504QString locateLocal( const char *type,
1505 const QString& filename/*US , const KInstance* inst*/ )
1506{
1507
1508 QString path = locateLocal(type, filename, true /*US, inst*/);
1509
1510
1511/*
1512 static int ccc = 0;
1513 ++ccc;
1514 if ( ccc > 13 )
1515 abort();
1516*/
1517 qDebug("locatelocal: %s" , path.latin1());
1518 return path;
1519
1520/*US why do we put all files into one directory. It is quit complicated.
1521why not staying with the original directorystructure ?
1522
1523
1524 QString escapedFilename = filename;
1525 escapedFilename.replace( QRegExp( "/" ), "_" );
1526
1527 QString path = KStandardDirs::appDir() + type + "_" + escapedFilename;
1528
1529 kdDebug() << "locate: '" << path << "'" << endl;
1530 qDebug("locate: %s" , path.latin1());
1531 return path;
1532*/
1533//US so my proposal is this:
1534
1535// QString escapedFilename = filename;
1536// escapedFilename.replace( QRegExp( "/" ), "_" );
1537
1538#if 0
1539#ifdef _WIN32_
1540 QString path = QDir::convertSeparators(KStandardDirs::appDir() + type + "/" + filename);
1541#else
1542 QString path = KStandardDirs::appDir() + type + "/" + filename;
1543#endif
1544
1545 //US Create the containing dir if needed
1546 QFileInfo fi ( path );
1547
1548 // QString dir=pathurl.directory();
1549 //QMessageBox::information( 0,"path", path, 1 );
1550
1551#ifdef _WIN32_
1552 KStandardDirs::makeDir(path);
1553#else
1554 KStandardDirs::makeDir(fi.dirPath( true ));
1555#endif
1556
1557 qDebug("locate22: %s" , path.latin1());
1558 return path;
1559
1560#endif
1561
1562}
1563
1564QString locateLocal( const char *type,
1565 const QString& filename, bool createDir/*US , const KInstance* inst*/ )
1566{
1567 // try to find slashes. If there are some, we have to
1568 // create the subdir first
1569 int slash = filename.findRev('/')+1;
1570 if (!slash) // only one filename
1571 //USreturn inst->dirs()->saveLocation(type, QString::null, createDir) + filename;
1572 return KGlobal::dirs()->saveLocation(type, QString::null, createDir) + filename;
1573
1574 // split path from filename
1575 QString dir = filename.left(slash);
1576 QString file = filename.mid(slash);
1577//US return inst->dirs()->saveLocation(type, dir, createDir) + file;
1578 return KGlobal::dirs()->saveLocation(type, dir, createDir) + file;
1579
1580 // ***************************************************************
1581#if 0
1582
1583/*US why do we put all files into one directory. It is quit complicated.
1584why not staying with the original directorystructure ?
1585
1586
1587 QString escapedFilename = filename;
1588 escapedFilename.replace( QRegExp( "/" ), "_" );
1589
1590 QString path = KStandardDirs::appDir() + type + "_" + escapedFilename;
1591
1592 kdDebug() << "locate: '" << path << "'" << endl;
1593 qDebug("locate: %s" , path.latin1());
1594 return path;
1595*/
1596//US so my proposal is this:
1597
1598// QString escapedFilename = filename;
1599// escapedFilename.replace( QRegExp( "/" ), "_" );
1600
1601#ifdef _WIN32_
1602 QString path = QDir::convertSeparators(KStandardDirs::appDir() + type + "/" + filename);
1603#else
1604 QString path = KStandardDirs::appDir() + type + "/" + filename;
1605#endif
1606
1607 //US Create the containing dir if needed
1608 KURL pathurl;
1609 pathurl.setPath(path);
1610 QString dir=pathurl.directory();
1611 //QMessageBox::information( 0,"path", path, 1 );
1612#ifdef _WIN32_
1613 KStandardDirs::makeDir(path);
1614#else
1615 KStandardDirs::makeDir(dir);
1616#endif
1617
1618 return path;
1619#endif
1620}
diff --git a/microkde/kdecore/kstandarddirs.h b/microkde/kdecore/kstandarddirs.h
new file mode 100644
index 0000000..c4e1108
--- a/dev/null
+++ b/microkde/kdecore/kstandarddirs.h
@@ -0,0 +1,681 @@
1/*
2 This file is part of the KDE libraries
3 Copyright (C) 1999 Sirtaj Singh Kang <taj@kde.org>
4 Stephan Kulow <coolo@kde.org>
5 Waldo Bastian <bastian@kde.org>
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Library General Public
9 License as published by the Free Software Foundation; either
10 version 2 of the License, or (at your option) any later version.
11
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Library General Public License for more details.
16
17 You should have received a copy of the GNU Library General Public License
18 along with this library; see the file COPYING.LIB. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.
21*/
22
23#ifndef SSK_KSTDDIRS_H
24#define SSK_KSTDDIRS_H
25
26#include <qstring.h>
27#include <qdict.h>
28#include <qstringlist.h>
29#include <kglobal.h>
30
31class KConfig;
32class KStandardDirsPrivate;
33
34
35/**
36 * @short Site-independent access to standard KDE directories.
37 * @author Stephan Kulow <coolo@kde.org> and Sirtaj Singh Kang <taj@kde.org>
38 * @version $Id$
39 *
40 * This is one of the most central classes in kdelibs as
41 * it provides a basic service: It knows where the files
42 * reside on the user's hard disk. And it's meant to be the
43 * only one that knows -- to make the real location as
44 * transparent as possible to both the user and the applications.
45 *
46 * To this end it insulates the application from all information
47 * and applications always refer to a file with a resource type
48 * (e.g. icon) and a filename (e.g. khexdit.xpm). In an ideal world
49 * the application would make no assumption where this file is and
50 * leave it up to @ref KStandardDirs::findResource("apps", "Home.desktop")
51 * to apply this knowledge to return /opt/kde/share/applnk/Home.desktop
52 * or ::locate("data", "kgame/background.jpg") to return
53 * /opt/kde/share/apps/kgame/background.jpg
54 *
55 * The main idea behind KStandardDirs is that there are several
56 * toplevel prefixes below which the files lie. One of these prefixes is
57 * the one where the user installed kdelibs, one is where the
58 * application was installed, and one is $HOME/.kde, but there
59 * may be even more. Under these prefixes there are several well
60 * defined suffixes where specific resource types are to be found.
61 * For example, for the resource type "html" the suffixes could be
62 * share/doc/HTML and share/doc/kde/HTML.
63 * So the search algorithm basicly appends to each prefix each registered
64 * suffix and tries to locate the file there.
65 * To make the thing even more complex, it's also possible to register
66 * absolute paths that KStandardDirs looks up after not finding anything
67 * in the former steps. They can be useful if the user wants to provide
68 * specific directories that aren't in his $HOME/.kde directory for,
69 * for example, icons.
70 *
71 * @sect Standard resources that kdelibs allocates are:
72 *
73 * @li apps - Applications menu (.desktop files).
74 * @li cache - Cached information (e.g. favicons, web-pages)
75 * @li cgi - CGIs to run from kdehelp.
76 * @li config - Configuration files.
77 * @li data - Where applications store data.
78 * @li exe - Executables in $prefix/bin. @ref findExe() for a function that takes $PATH into account.
79 * @li html - HTML documentation.
80 * @li icon - Icons, see @ref KIconLoader.
81 * @li lib - Libraries.
82 * @li locale - Translation files for @ref KLocale.
83 * @li mime - Mime types.
84 * @li module - Module (dynamically loaded library).
85 * @li qtplugins - Qt plugins (dynamically loaded objects for Qt)
86 * @li services - Services.
87 * @li servicetypes - Service types.
88 * @li scripts - Application scripting additions.
89 * @li sound - Application sounds.
90 * @li templates - Templates
91 * @li wallpaper - Wallpapers.
92 * @li tmp - Temporary files (specfic for both current host and current user)
93 * @li socket - UNIX Sockets (specific for both current host and current user)
94 *
95 * A type that is added by the class @ref KApplication if you use it, is
96 * appdata. This one makes the use of the type data a bit easier as it
97 * appends the name of the application.
98 * So while you had to ::locate("data", "appname/filename") so you can
99 * also write ::locate("appdata", "filename") if your KApplication instance
100 * is called "appname" (as set via KApplication's constructor or KAboutData, if
101 * you use the global KStandardDirs object @ref KGlobal::dirs()).
102 * Please note though that you cannot use the "appdata"
103 * type if you intend to use it in an applet for Kicker because 'appname' would
104 * be "Kicker" instead of the applet's name. Therefore, for applets, you've got
105 * to work around this by using ::locate("data", "appletname/filename").
106 *
107 * @sect KStandardDirs supports the following environment variables:
108 *
109 * @li KDEDIRS: This may set an additional number of directory prefixes to
110 * search for resources. The directories should be seperated
111 * by ':'. The directories are searched in the order they are
112 * specified.
113 * @li KDEDIR: Used for backwards compatibility. As KDEDIRS but only a single
114 * directory may be specified. If KDEDIRS is set KDEDIR is
115 * ignored.
116 * @li KDEHOME: The directory where changes are saved to. This directory is
117 * used to search for resources first. If KDEHOME is not
118 * specified it defaults to "$HOME/.kde"
119 * @li KDEROOTHOME: Like KDEHOME, but used for the root user.
120 * If KDEROOTHOME is not set it defaults to the .kde directory in the
121 * home directory of root, usually "/root/.kde".
122 * Note that the setting of $HOME is ignored in this case.
123 *
124 * @see KGlobalSettings
125 */
126class KStandardDirs
127{
128public:
129 /**
130 * KStandardDirs' constructor. It just initializes the caches.
131 **/
132 KStandardDirs( );
133
134 /**
135 * KStandardDirs' destructor.
136 */
137 virtual ~KStandardDirs();
138
139 /**
140 * Adds another search dir to front of the @p fsstnd list.
141 *
142 * @li When compiling kdelibs, the prefix is added to this.
143 * @li KDEDIRS or KDEDIR is taking into account
144 * @li Additional dirs may be loaded from kdeglobals.
145 *
146 * @param dir The directory to append relative paths to.
147 */
148 void addPrefix( const QString& dir );
149
150 /**
151 * Adds another search dir to front of the XDG_CONFIG_XXX list
152 * of prefixes.
153 * This prefix is only used for resources that start with "xdgconf-"
154 *
155 * @param dir The directory to append relative paths to.
156 */
157 void addXdgConfigPrefix( const QString& dir );
158
159 /**
160 * Adds another search dir to front of the XDG_DATA_XXX list
161 * of prefixes.
162 * This prefix is only used for resources that start with "xdgdata-"
163 *
164 * @param dir The directory to append relative paths to.
165 */
166 void addXdgDataPrefix( const QString& dir );
167
168 /**
169 * Adds suffixes for types.
170 *
171 * You may add as many as you need, but it is advised that there
172 * is exactly one to make writing definite.
173 * All basic types (@ref kde_default) are added by @ref addKDEDefaults(),
174 * but for those you can add more relative paths as well.
175 *
176 * The later a suffix is added, the higher its priority. Note, that the
177 * suffix should end with / but doesn't have to start with one (as prefixes
178 * should end with one). So adding a suffix for app_pics would look
179 * like KGlobal::dirs()->addResourceType("app_pics", "share/app/pics");
180 *
181 * @param type Specifies a short descriptive string to access
182 * files of this type.
183 * @param relativename Specifies a directory relative to the root
184 * of the KFSSTND.
185 * @return true if successful, false otherwise.
186 */
187 bool addResourceType( const char *type,
188 const QString& relativename );
189
190 /**
191 * Adds absolute path at the end of the search path for
192 * particular types (for example in case of icons where
193 * the user specifies extra paths).
194 *
195 * You shouldn't need this
196 * function in 99% of all cases besides adding user-given
197 * paths.
198 *
199 * @param type Specifies a short descriptive string to access files
200 * of this type.
201 * @param absdir Points to directory where to look for this specific
202 * type. Non-existant directories may be saved but pruned.
203 * @return true if successful, false otherwise.
204 */
205 bool addResourceDir( const char *type,
206 const QString& absdir);
207
208 /**
209 * Tries to find a resource in the following order:
210 * @li All PREFIX/\<relativename> paths (most recent first).
211 * @li All absolute paths (most recent first).
212 *
213 * The filename should be a filename relative to the base dir
214 * for resources. So is a way to get the path to libkdecore.la
215 * to findResource("lib", "libkdecore.la"). KStandardDirs will
216 * then look into the subdir lib of all elements of all prefixes
217 * ($KDEDIRS) for a file libkdecore.la and return the path to
218 * the first one it finds (e.g. /opt/kde/lib/libkdecore.la)
219 *
220 * @param type The type of the wanted resource
221 * @param filename A relative filename of the resource.
222 *
223 * @return A full path to the filename specified in the second
224 * argument, or QString::null if not found.
225 */
226 QString findResource( const char *type,
227 const QString& filename ) const;
228
229 /**
230 * Checks whether a resource is restricted as part of the KIOSK
231 * framework. When a resource is restricted it means that user-
232 * specific files in the resource are ignored.
233 *
234 * E.g. by restricting the "wallpaper" resource, only system-wide
235 * installed wallpapers will be found by this class. Wallpapers
236 * installed under the $KDEHOME directory will be ignored.
237 *
238 * @param type The type of the resource to check
239 * @param relPath A relative path in the resource.
240 *
241 * @return True if the resource is restricted.
242 * @since 3.1
243 */
244 bool isRestrictedResource( const char *type,
245 const QString& relPath=QString::null ) const;
246
247 /**
248 * Returns a number that identifies this version of the resource.
249 * When a change is made to the resource this number will change.
250 *
251 * @param type The type of the wanted resource
252 * @param filename A relative filename of the resource.
253 * @param deep If true, all resources are taken into account
254 * otherwise only the one returned by findResource().
255 *
256 * @return A number identifying the current version of the
257 * resource.
258 */
259/*US
260 Q_UINT32 calcResourceHash( const char *type,
261 const QString& filename, bool deep) const;
262*/
263 /**
264 * Tries to find all directories whose names consist of the
265 * specified type and a relative path. So would
266 * findDirs("apps", "Settings") return
267 * @li /opt/kde/share/applnk/Settings/
268 * @li /home/joe/.kde/share/applnk/Settings/
269 *
270 * Note that it appends / to the end of the directories,
271 * so you can use this right away as directory names.
272 *
273 * @param type The type of the base directory.
274 * @param reldir Relative directory.
275 *
276 * @return A list of matching directories, or an empty
277 * list if the resource specified is not found.
278 */
279 QStringList findDirs( const char *type,
280 const QString& reldir ) const;
281
282 /**
283 * Tries to find the directory the file is in.
284 * It works the same as @ref findResource(), but it doesn't
285 * return the filename but the name of the directory.
286 *
287 * This way the application can access a couple of files
288 * that have been installed into the same directory without
289 * having to look for each file.
290 *
291 * findResourceDir("lib", "libkdecore.la") would return the
292 * path of the subdir libkdecore.la is found first in
293 * (e.g. /opt/kde/lib/)
294 *
295 * @param type The type of the wanted resource
296 * @param filename A relative filename of the resource.
297 * @return The directory where the file specified in the second
298 * argument is located, or QString::null if the type
299 * of resource specified is unknown or the resource
300 * cannot be found.
301 */
302 QString findResourceDir( const char *type,
303 const QString& filename) const;
304
305
306 /**
307 * Tries to find all resources with the specified type.
308 *
309 * The function will look into all specified directories
310 * and return all filenames in these directories.
311 *
312 * @param type The type of resource to locate directories for.
313 * @param filter Only accept filenames that fit to filter. The filter
314 * may consist of an optional directory and a @ref QRegExp
315 * wildcard expression. E.g. "images\*.jpg". Use QString::null
316 * if you do not want a filter.
317 * @param recursive Specifies if the function should decend
318 * into subdirectories.
319 * @param uniq If specified, only return items which have
320 * unique suffixes - suppressing duplicated filenames.
321 *
322 * @return A list of directories matching the resource specified,
323 * or an empty list if the resource type is unknown.
324 */
325 QStringList findAllResources( const char *type,
326 const QString& filter = QString::null,
327 bool recursive = false,
328 bool uniq = false) const;
329
330 /**
331 * Tries to find all resources with the specified type.
332 *
333 * The function will look into all specified directories
334 * and return all filenames (full and relative paths) in
335 * these directories.
336 *
337 * @param type The type of resource to locate directories for.
338 * @param filter Only accept filenames that fit to filter. The filter
339 * may consist of an optional directory and a @ref QRegExp
340 * wildcard expression. E.g. "images\*.jpg". Use QString::null
341 * if you do not want a filter.
342 * @param recursive Specifies if the function should decend
343 * into subdirectories.
344 * @param uniq If specified, only return items which have
345 * unique suffixes.
346 * @param list Of relative paths for the given type.
347 * @param relPaths The list to store the relative paths into
348 * These can be used later to ::locate() the file
349 *
350 * @return A list of directories matching the resource specified,
351 * or an empty list if the resource type is unknown.
352 */
353 QStringList findAllResources( const char *type,
354 const QString& filter,
355 bool recursive,
356 bool uniq,
357 QStringList &relPaths) const;
358
359 /**
360 * Finds the executable in the system path.
361 *
362 * A valid executable must
363 * be a file and have its executable bit set.
364 *
365 * @param appname The name of the executable file for which to search.
366 * @param pathstr The path which will be searched. If this is
367 * null (default), the $PATH environment variable will
368 * be searched.
369 * @param ignoreExecBitIf true, an existing file will be returned
370 * even if its executable bit is not set.
371 *
372 * @return The path of the executable. If it was not found,
373 * it will return QString::null.
374 * @see findAllExe()
375 */
376/*US
377 static QString findExe( const QString& appname,
378 const QString& pathstr=QString::null,
379 bool ignoreExecBit=false );
380*/
381
382 /**
383 * Finds all occurences of an executable in the system path.
384 *
385 * @param listWill be filled with the pathnames of all the
386 * executables found. Will be empty if the executable
387 * was not found.
388 * @param appnameThe name of the executable for which to
389 * search.
390 * @param pathstrThe path list which will be searched. If this
391 * is 0 (default), the $PATH environment variable will
392 * be searched.
393 * @param ignoreExecBit If true, an existing file will be returned
394 * even if its executable bit is not set.
395 *
396 * @return The number of executables found, 0 if none were found.
397 *
398 * @seefindExe()
399 */
400 static int findAllExe( QStringList& list, const QString& appname,
401 const QString& pathstr=QString::null,
402 bool ignoreExecBit=false );
403
404 /**
405 * This function adds the defaults that are used by the current
406 * KDE version.
407 *
408 * It's a series of @ref addResourceTypes()
409 * and @ref addPrefix() calls.
410 * You normally wouldn't call this function because it's called
411 * for you from @ref KGlobal.
412 */
413 void addKDEDefaults();
414
415 /**
416 * Reads customized entries out of the given config object and add
417 * them via @ref addResourceDirs().
418 *
419 * @param config The object the entries are read from. This should
420 * contain global config files
421 * @return true if new config paths have been added
422 * from @p config.
423 **/
424 bool addCustomized(KConfig *config);
425
426 /**
427 * This function is used internally by almost all other function as
428 * it serves and fills the directories cache.
429 *
430 * @param type The type of resource
431 * @return The list of possible directories for the specified @p type.
432 * The function updates the cache if possible. If the resource
433 * type specified is unknown, it will return an empty list.
434 * Note, that the directories are assured to exist beside the save
435 * location, which may not exist, but is returned anyway.
436 */
437 QStringList resourceDirs(const char *type) const;
438
439 /**
440 * This function will return a list of all the types that KStandardDirs
441 * supports.
442 *
443 * @return All types that KDE supports
444 */
445 QStringList allTypes() const;
446
447 /**
448 * Finds a location to save files into for the given type
449 * in the user's home directory.
450 *
451 * @param type The type of location to return.
452 * @param suffix A subdirectory name.
453 * Makes it easier for you to create subdirectories.
454 * You can't pass filenames here, you _have_ to pass
455 * directory names only and add possible filename in
456 * that directory yourself. A directory name always has a
457 * trailing slash ('/').
458 * @param create If set, saveLocation() will create the directories
459 * needed (including those given by @p suffix).
460 *
461 * @return A path where resources of the specified type should be
462 * saved, or QString::null if the resource type is unknown.
463 */
464 QString saveLocation(const char *type,
465 const QString& suffix = QString::null,
466 bool create = true) const;
467
468 /**
469 * Converts an absolute path to a path relative to a certain
470 * resource.
471 *
472 * If "abs = ::locate(resource, rel)"
473 * then "rel = relativeLocation(resource, abs)" and vice versa.
474 *
475 * @param type The type of resource.
476 *
477 * @param absPath An absolute path to make relative.
478 *
479 * @return A relative path relative to resource @p type that
480 * will find @p absPath. If no such relative path exists, absPath
481 * will be returned unchanged.
482 */
483 QString relativeLocation(const char *type, const QString &absPath);
484
485 /**
486 * Recursively creates still-missing directories in the given path.
487 *
488 * The resulting permissions will depend on the current umask setting.
489 * permission = mode & ~umask.
490 *
491 * @param dir Absolute path of the directory to be made.
492 * @param mode Directory permissions.
493 * @return true if successful, false otherwise
494 */
495 static bool makeDir(const QString& dir, int mode = 0755);
496
497 /**
498 * This returns a default relative path for the standard KDE
499 * resource types. Below is a list of them so you get an idea
500 * of what this is all about.
501 *
502 * @li data - share/apps
503 * @li html - share/doc/HTML
504 * @li icon - share/icon
505 * @li config - share/config
506 * @li pixmap - share/pixmaps
507 * @li apps - share/applnk
508 * @li sound - share/sounds
509 * @li locale - share/locale
510 * @li services - share/services
511 * @li servicetypes - share/servicetypes
512 * @li mime - share/mimelnk
513 * @li wallpaper - share/wallpapers
514 * @li templates - share/templates
515 * @li exe - bin
516 * @li lib - lib
517 *
518 * @returns Static default for the specified resource. You
519 * should probably be using locate() or locateLocal()
520 * instead.
521 * @see locate()
522 * @see locateLocal()
523 */
524 static QString kde_default(const char *type);
525
526 /**
527 * @internal (for use by sycoca only)
528 */
529 QString kfsstnd_prefixes();
530
531 /**
532 * Returns the toplevel directory in which KStandardDirs
533 * will store things. Most likely $HOME/.kde
534 * Don't use this function if you can use locateLocal
535 * @return the toplevel directory
536 */
537 QString localkdedir() const;
538
539 /**
540 * @return $XDG_DATA_HOME
541 * See also http://www.freedesktop.org/standards/basedir/draft/basedir-spec/basedir-spec.html
542 */
543 QString localxdgdatadir() const;
544
545 /**
546 * @return $XDG_CONFIG_HOME
547 * See also http://www.freedesktop.org/standards/basedir/draft/basedir-spec/basedir-spec.html
548 */
549 QString localxdgconfdir() const;
550
551 /**
552 * Checks for existence and accessability.
553 * Faster than creating a QFileInfo first.
554 * @param fullPath the path to check
555 * @return true if the directory exists
556 */
557 static bool exists(const QString &fullPath);
558
559 /**
560 * Expands all symbolic links and resolves references to
561 * '/./', '/../' and extra '/' characters in @p dirname
562 * and returns the canonicalized absolute pathname.
563 * The resulting path will have no symbolic link, '/./'
564 * or '/../' components.
565 * @since 3.1
566 */
567 static QString realPath(const QString &dirname);
568
569 static void setAppDir( const QString & );
570 static QString appDir();
571
572 private:
573
574 QStringList prefixes;
575
576 // Directory dictionaries
577 QDict<QStringList> absolutes;
578 QDict<QStringList> relatives;
579
580 mutable QDict<QStringList> dircache;
581 mutable QDict<QString> savelocations;
582
583 // Disallow assignment and copy-construction
584 KStandardDirs( const KStandardDirs& );
585 KStandardDirs& operator= ( const KStandardDirs& );
586
587 bool addedCustoms;
588
589 class KStandardDirsPrivate;
590 KStandardDirsPrivate *d;
591//US
592 static QString mAppDir;
593
594 void checkConfig() const;
595 void applyDataRestrictions(const QString &) const;
596 //US void createSpecialResource(const char*);
597};
598
599/**
600 * \addtogroup locates Locate Functions
601 * @{
602 * On The Usage Of 'locate' and 'locateLocal'
603 *
604 * Typical KDE applications use resource files in one out of
605 * three ways:
606 *
607 * 1) A resource file is read but is never written. A system
608 * default is supplied but the user can override this
609 * default in his local .kde directory:
610 *
611 * \code
612 * // Code example
613 * myFile = locate("appdata", "groups.lst");
614 * myData = myReadGroups(myFile); // myFile may be null
615 * \endcode
616 *
617 * 2) A resource file is read and written. If the user has no
618 * local version of the file the system default is used.
619 * The resource file is always written to the users local
620 * .kde directory.
621 *
622 * \code
623 * // Code example
624 * myFile = locate("appdata", "groups.lst")
625 * myData = myReadGroups(myFile);
626 * ...
627 * doSomething(myData);
628 * ...
629 * myFile = locateLocal("appdata", "groups.lst");
630 * myWriteGroups(myFile, myData);
631 * \endcode
632 *
633 * 3) A resource file is read and written. No system default
634 * is used if the user has no local version of the file.
635 * The resource file is always written to the users local
636 * .kde directory.
637 *
638 * \code
639 * // Code example
640 * myFile = locateLocal("appdata", "groups.lst");
641 * myData = myReadGroups(myFile);
642 * ...
643 * doSomething(myData);
644 * ...
645 * myFile = locateLocal("appdata", "groups.lst");
646 * myWriteGroups(myFile, myData);
647 * \endcode
648 **/
649
650/*!
651 * \relates KStandardDirs
652 * This function is just for convenience. It simply calls
653 *instance->dirs()->\link KStandardDirs::findResource() findResource\endlink(type, filename).
654 **/
655QString locate( const char *type, const QString& filename /*US , const KInstance* instance = KGlobal::instance()*/ );
656
657/*!
658 * \relates KStandardDirs
659 * This function is much like locate. However it returns a
660 * filename suitable for writing to. No check is made if the
661 * specified filename actually exists. Missing directories
662 * are created. If filename is only a directory, without a
663 * specific file, filename must have a trailing slash.
664 *
665 **/
666QString locateLocal( const char *type, const QString& filename /*US , const KInstance* instance = KGlobal::instance() */ );
667
668/*!
669 * \relates KStandardDirs
670 * This function is much like locate. No check is made if the
671 * specified filename actually exists. Missing directories
672 * are created if @p createDir is true. If filename is only
673 * a directory, without a specific file,
674 * filename must have a trailing slash.
675 *
676 **/
677QString locateLocal( const char *type, const QString& filename, bool createDir /*US , const KInstance* instance = KGlobal::instance() */);
678
679/*! @} */
680
681#endif // SSK_KSTDDIRS_H
diff --git a/microkde/kdecore/kstringhandler.cpp b/microkde/kdecore/kstringhandler.cpp
new file mode 100644
index 0000000..b737e97
--- a/dev/null
+++ b/microkde/kdecore/kstringhandler.cpp
@@ -0,0 +1,650 @@
1/* This file is part of the KDE libraries
2 Copyright (C) 1999 Ian Zepp (icszepp@islc.net)
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA.
18*/
19
20/* AIX needs strings.h for str*casecmp(), and our config.h loads it on AIX
21 So we don't need to include strings.h explicitly */
22
23//US #include "config.h"
24
25#include "kstringhandler.h"
26/*US
27QString KStringHandler::word( const QString &text , uint pos )
28{
29 QStringList list = QStringList::split( " ", text , true );
30
31 if ( pos < list.count() )
32 return list[ pos ];
33
34 return "";
35}
36
37QString KStringHandler::word( const QString &text , const char *range )
38{
39 // Format in: START:END
40 // Note index starts a 0 (zero)
41 //
42 // 0: first word to end
43 // 1:3 second to fourth words
44 QStringList list = QStringList::split( " ", text , true );
45 QString tmp = "";
46 QString r = range;
47
48 if ( text.isEmpty() )
49 return tmp;
50
51 // do stuff here
52 QRegExp reg;
53
54 int at = 0;
55 int pos = 0;
56 int cnt = 0;
57
58 if ( r.find(QRegExp("[0-9]+:[0-9]+")) != -1 )
59 {
60 at = r.find(":");
61 pos = atoi( r.left(at).ascii() );
62 cnt = atoi( r.remove(0,at+1).ascii() );
63 }
64 else if ( r.find(QRegExp(":+[0-9]+")) != -1 )
65 {
66 at = r.find(":");
67 pos = 0;
68 cnt = atoi( r.remove(0,at+1).ascii() );
69 }
70 else if ( r.find(QRegExp("[0-9]+:+")) != -1 )
71 {
72 at = r.find(":");
73 pos = atoi( r.left(at).ascii() );
74 cnt = list.count(); // zero index
75 }
76 else if ( r.find(QRegExp("[0-9]+")) != -1 )
77 {
78 pos = atoi( r.ascii() );
79 cnt = pos;
80 }
81 else
82 {
83 return tmp; // not found/implemented
84 }
85
86 //
87 // Extract words
88 //
89 int wordsToExtract = cnt-pos+1;
90 QStringList::Iterator it = list.at( pos);
91
92 while ( (it != list.end()) && (wordsToExtract-- > 0))
93 {
94 tmp += *it;
95 tmp += " ";
96 it++;
97 }
98
99 return tmp.stripWhiteSpace();
100}
101
102//
103// Insertion and removal routines
104//
105QString KStringHandler::insword( const QString &text , const QString &word , uint pos )
106{
107 if ( text.isEmpty() )
108 return word;
109
110 if ( word.isEmpty() )
111 return text;
112
113 // Split words and add into list
114 QStringList list = QStringList::split( " ", text, true );
115
116 if ( pos >= list.count() )
117 list.append( word );
118 else
119 list.insert( list.at(pos) , word );
120
121 // Rejoin
122 return list.join( " " );
123}
124
125QString KStringHandler::setword( const QString &text , const QString &word , uint pos )
126{
127 if ( text.isEmpty() )
128 return word;
129
130 if ( word.isEmpty() )
131 return text;
132
133 // Split words and add into list
134 QStringList list = QStringList::split( " ", text, true );
135
136 if ( pos >= list.count() )
137 list.append( word );
138 else
139 {
140 list.insert( list.remove( list.at(pos) ) , word );
141 }
142
143 // Rejoin
144 return list.join( " " );
145}
146
147QString KStringHandler::remrange( const QString &text , const char *range )
148{
149 // Format in: START:END
150 // Note index starts a 0 (zero)
151 //
152 // 0: first word to end
153 // 1:3 second to fourth words
154 QStringList list = QStringList::split( " ", text , true );
155 QString tmp = "";
156 QString r = range;
157
158 if ( text.isEmpty() )
159 return tmp;
160
161 // do stuff here
162 QRegExp reg;
163
164 int at = 0;
165 int pos = 0;
166 int cnt = 0;
167
168 if ( r.find(QRegExp("[0-9]+:[0-9]+")) != -1 )
169 {
170 at = r.find(':');
171 pos = atoi( r.left(at).ascii() );
172 cnt = atoi( r.remove(0,at+1).ascii() );
173 }
174 else if ( r.find(QRegExp(":+[0-9]+")) != -1 )
175 {
176 at = r.find(':');
177 pos = 0;
178 cnt = atoi( r.remove(0,at+1).ascii() );
179 }
180 else if ( r.find(QRegExp("[0-9]+:+")) != -1 )
181 {
182 at = r.find(':');
183 pos = atoi( r.left(at).ascii() );
184 cnt = list.count(); // zero index
185 }
186 else if ( r.find(QRegExp("[0-9]+")) != -1 )
187 {
188 pos = atoi( r.ascii() );
189 cnt = pos;
190 }
191 else
192 {
193 return text; // not found/implemented
194 }
195
196 //
197 // Remove that range of words
198 //
199 int wordsToDelete = cnt-pos+1;
200 QStringList::Iterator it = list.at( pos);
201
202 while ( (it != list.end()) && (wordsToDelete-- > 0))
203 it = list.remove( it );
204
205 return list.join( " " );
206}
207
208QString KStringHandler::remword( const QString &text , uint pos )
209{
210 QString tmp = "";
211
212 if ( text.isEmpty() )
213 return tmp;
214
215 // Split words and add into list
216 QStringList list = QStringList::split( " ", text, true );
217
218 if ( pos < list.count() )
219 list.remove( list.at( pos ) );
220
221 // Rejoin
222 return list.join( " " );
223}
224
225QString KStringHandler::remword( const QString &text , const QString &word )
226{
227 QString tmp = "";
228
229 if ( text.isEmpty() )
230 return tmp;
231
232 if ( word.isEmpty() )
233 return text;
234
235 // Split words and add into list
236 QStringList list = QStringList::split( " ", text, true );
237
238 QStringList::Iterator it = list.find(word);
239
240 if (it != list.end())
241 list.remove( it );
242
243 // Rejoin
244 return list.join( " " );
245}
246
247//
248// Capitalization routines
249//
250QString KStringHandler::capwords( const QString &text )
251{
252 QString tmp = "";
253
254 if ( text.isEmpty() )
255 return tmp;
256
257 QStringList list = QStringList::split( " ", text, true );
258
259 return capwords( QStringList::split( " ", text, true )).join( " " );
260}
261
262QStringList KStringHandler::capwords( const QStringList &list )
263{
264 QStringList tmp;
265 QString word;
266
267 if ( list.count() == 0 )
268 return tmp;
269
270 for ( QStringList::ConstIterator it= list.begin();
271 it != list.end();
272 it++)
273 {
274 word = *it;
275 word = word.left(1).upper() + word.remove(0,1);
276
277 tmp.append( word ); // blank list to start with
278 }
279
280 return tmp;
281}
282
283//
284// Reverse routines
285//
286QString KStringHandler::reverse( const QString &text )
287{
288 QString tmp;
289
290 if ( text.isEmpty() )
291 return tmp;
292
293 QStringList list;
294 list = QStringList::split( " ", text, true );
295 list = reverse( list );
296
297 return list.join( " " );
298}
299
300QStringList KStringHandler::reverse( const QStringList &list )
301{
302 QStringList tmp;
303
304 if ( list.count() == 0 )
305 return tmp;
306
307 for ( QStringList::ConstIterator it= list.begin();
308 it != list.end();
309 it++)
310 tmp.prepend( *it );
311
312 return tmp;
313}
314
315//
316// Left, Right, Center justification
317//
318QString KStringHandler::ljust( const QString &text , uint width )
319{
320 QString tmp = text;
321 tmp = tmp.stripWhiteSpace(); // remove leading/trailing spaces
322
323 if ( tmp.length() >= width )
324 return tmp;
325
326 for ( uint pos = tmp.length() ; pos < width ; pos++ )
327 tmp.append(" ");
328
329 return tmp;
330}
331
332QString KStringHandler::rjust( const QString &text , uint width )
333{
334 QString tmp = text;
335 tmp = tmp.stripWhiteSpace(); // remove leading/trailing spaces
336
337 if ( tmp.length() >= width )
338 return tmp;
339
340 for ( uint pos = tmp.length() ; pos < width ; pos++ )
341 tmp.prepend(" ");
342
343 return tmp;
344}
345
346QString KStringHandler::center( const QString &text , uint width )
347{
348 // Center is slightly different, in that it will add
349 // spaces to the RIGHT side (left-justified) before
350 // it adds a space to the LEFT side.
351
352 QString tmp = text;
353 tmp = tmp.stripWhiteSpace(); // remove leading/trailing spaces
354
355 if ( tmp.length() >= width )
356 return tmp;
357
358 bool left = false; // start at right side.
359
360 for ( uint pos = tmp.length() ; pos < width ; pos++ )
361 {
362 if ( left )
363 tmp.prepend(" ");
364 else
365 tmp.append(" ");
366
367 // Reverse bool
368 left = !left;
369 }
370
371 return tmp;
372}
373
374QString KStringHandler::lsqueeze( const QString & str, uint maxlen )
375{
376 if (str.length() > maxlen) {
377 int part = maxlen-3;
378 return QString("..." + str.right(part));
379 }
380 else return str;
381}
382
383QString KStringHandler::csqueeze( const QString & str, uint maxlen )
384{
385 if (str.length() > maxlen && maxlen > 3) {
386 int part = (maxlen-3)/2;
387 return QString(str.left(part) + "..." + str.right(part));
388 }
389 else return str;
390}
391
392QString KStringHandler::rsqueeze( const QString & str, uint maxlen )
393{
394 if (str.length() > maxlen) {
395 int part = maxlen-3;
396 return QString(str.left(part) + "...");
397 }
398 else return str;
399}
400
401QString KStringHandler::lEmSqueeze(const QString &name, const QFontMetrics& fontMetrics, uint maxlen)
402{
403 return lPixelSqueeze(name, fontMetrics, fontMetrics.maxWidth() * maxlen);
404}
405
406static inline int emSqueezeLimit(int delta, int min, int max)
407{
408 if (delta < min) return min;
409 if (delta > max) return max;
410 return delta;
411}
412
413QString KStringHandler::lPixelSqueeze(const QString& name, const QFontMetrics& fontMetrics, uint maxPixels)
414{
415 uint nameWidth = fontMetrics.width(name);
416
417 if (maxPixels < nameWidth)
418 {
419 QString tmp = name;
420 const uint em = fontMetrics.maxWidth();
421 maxPixels -= fontMetrics.width("...");
422
423 while (maxPixels < nameWidth && !tmp.isEmpty())
424 {
425 int delta = (nameWidth - maxPixels) / em;
426 delta = emSqueezeLimit(delta, 1, delta); // no max
427
428 tmp.remove(0, delta);
429 nameWidth = fontMetrics.width(tmp);
430 }
431
432 return ("..." + tmp);
433 }
434
435 return name;
436}
437
438QString KStringHandler::cEmSqueeze(const QString& name, const QFontMetrics& fontMetrics, uint maxlen)
439{
440 return cPixelSqueeze(name, fontMetrics, fontMetrics.maxWidth() * maxlen);
441}
442
443QString KStringHandler::cPixelSqueeze(const QString& name, const QFontMetrics& fontMetrics, uint maxPixels)
444{
445 uint nameWidth = fontMetrics.width(name);
446
447 if (maxPixels < nameWidth)
448 {
449 QString tmp = name;
450 const uint em = fontMetrics.maxWidth();
451 maxPixels -= fontMetrics.width("...");
452
453 while (maxPixels < nameWidth && !tmp.isEmpty())
454 {
455 int length = tmp.length();
456 int delta = (nameWidth - maxPixels) / em;
457 delta = emSqueezeLimit(delta, 1, length) ;
458
459 tmp.remove((length / 2) - (delta / 2), delta);
460 nameWidth = fontMetrics.width(tmp);
461 }
462
463 return tmp.insert((tmp.length() + 1) / 2, "...");
464 }
465
466 return name;
467}
468
469QString KStringHandler::rEmSqueeze(const QString& name, const QFontMetrics& fontMetrics, uint maxlen)
470{
471 return rPixelSqueeze(name, fontMetrics, fontMetrics.maxWidth() * maxlen);
472}
473
474QString KStringHandler::rPixelSqueeze(const QString& name, const QFontMetrics& fontMetrics, uint maxPixels)
475{
476 uint nameWidth = fontMetrics.width(name);
477
478 if (maxPixels < nameWidth)
479 {
480 QString tmp = name;
481 const uint em = fontMetrics.maxWidth();
482 maxPixels -= fontMetrics.width("...");
483
484 while (maxPixels < nameWidth && !tmp.isEmpty())
485 {
486 int length = tmp.length();
487 int delta = (nameWidth - maxPixels) / em;
488 delta = emSqueezeLimit(delta, 1, length) ;
489
490 tmp.remove(length - delta, delta);
491 nameWidth = fontMetrics.width(tmp);
492 }
493
494 return (tmp + "...");
495 }
496
497 return name;
498}
499
500///// File name patterns (like *.txt)
501
502bool KStringHandler::matchFileName( const QString& filename, const QString& pattern )
503{
504 int len = filename.length();
505 int pattern_len = pattern.length();
506
507 if (!pattern_len)
508 return false;
509
510 // Patterns like "Makefile*"
511 if ( pattern[ pattern_len - 1 ] == '*' && len + 1 >= pattern_len ) {
512 const QChar *c1 = pattern.unicode();
513 const QChar *c2 = filename.unicode();
514 int cnt = 1;
515 while ( cnt < pattern_len && *c1++ == *c2++ )
516 ++cnt;
517 return cnt == pattern_len;
518 }
519
520 // Patterns like "*~", "*.extension"
521 if ( pattern[ 0 ] == '*' && len + 1 >= pattern_len )
522 {
523 const QChar *c1 = pattern.unicode() + pattern_len - 1;
524 const QChar *c2 = filename.unicode() + len - 1;
525 int cnt = 1;
526 while ( cnt < pattern_len && *c1-- == *c2-- )
527 ++cnt;
528 return cnt == pattern_len;
529 }
530
531 // Patterns like "Makefile"
532 return ( filename == pattern );
533}
534
535 QStringList
536KStringHandler::perlSplit(const QString & sep, const QString & s, uint max)
537{
538 bool ignoreMax = 0 == max;
539
540 QStringList l;
541
542 int searchStart = 0;
543
544 int tokenStart = s.find(sep, searchStart);
545
546 while (-1 != tokenStart && (ignoreMax || l.count() < max - 1))
547 {
548 if (!s.mid(searchStart, tokenStart - searchStart).isEmpty())
549 l << s.mid(searchStart, tokenStart - searchStart);
550
551 searchStart = tokenStart + sep.length();
552 tokenStart = s.find(sep, searchStart);
553 }
554
555 if (!s.mid(searchStart, s.length() - searchStart).isEmpty())
556 l << s.mid(searchStart, s.length() - searchStart);
557
558 return l;
559}
560
561 QStringList
562KStringHandler::perlSplit(const QChar & sep, const QString & s, uint max)
563{
564 bool ignoreMax = 0 == max;
565
566 QStringList l;
567
568 int searchStart = 0;
569
570 int tokenStart = s.find(sep, searchStart);
571
572 while (-1 != tokenStart && (ignoreMax || l.count() < max - 1))
573 {
574 if (!s.mid(searchStart, tokenStart - searchStart).isEmpty())
575 l << s.mid(searchStart, tokenStart - searchStart);
576
577 searchStart = tokenStart + 1;
578 tokenStart = s.find(sep, searchStart);
579 }
580
581 if (!s.mid(searchStart, s.length() - searchStart).isEmpty())
582 l << s.mid(searchStart, s.length() - searchStart);
583
584 return l;
585}
586
587 QStringList
588KStringHandler::perlSplit(const QRegExp & sep, const QString & s, uint max)
589{
590 bool ignoreMax = 0 == max;
591
592 QStringList l;
593
594 int searchStart = 0;
595 int tokenStart = sep.search(s, searchStart);
596 int len = sep.matchedLength();
597
598 while (-1 != tokenStart && (ignoreMax || l.count() < max - 1))
599 {
600 if (!s.mid(searchStart, tokenStart - searchStart).isEmpty())
601 l << s.mid(searchStart, tokenStart - searchStart);
602
603 searchStart = tokenStart + len;
604 tokenStart = sep.search(s, searchStart);
605 len = sep.matchedLength();
606 }
607
608 if (!s.mid(searchStart, s.length() - searchStart).isEmpty())
609 l << s.mid(searchStart, s.length() - searchStart);
610
611 return l;
612}
613US end */
614
615/*US
616 QString
617KStringHandler::tagURLs( const QString& text )
618{
619 QRegExp urlEx("(www\\.(?!\\.)|(f|ht)tp(|s)://)[\\d\\w\\./,:_~\\?=&;#@\\-\\+\\%]+[\\d\\w/]");
620
621 QString richText( text );
622 int urlPos = 0, urlLen;
623 while ((urlPos = urlEx.search(richText, urlPos)) >= 0)
624 {
625 urlLen = urlEx.matchedLength();
626 QString href = richText.mid( urlPos, urlLen );
627 // Qt doesn't support (?<=pattern) so we do it here
628 if((urlPos > 0) && richText[urlPos-1].isLetterOrNumber()){
629 urlPos++;
630 continue;
631 }
632 // Don't use QString::arg since %01, %20, etc could be in the string
633 QString anchor = "<a href=\"" + href + "\">" + href + "</a>";
634 richText.replace( urlPos, urlLen, anchor );
635
636
637 urlPos += anchor.length();
638 }
639 return richText;
640}
641*/
642QString KStringHandler::obscure( const QString &str )
643{
644 QString result;
645 for ( uint i = 0; i < str.length(); ++i )
646 result += ( str.at( i ).unicode() < 0x20 ) ? str.at( i ) :
647 QChar( 0x1001F - str.at( i ).unicode() );
648
649 return result;
650}
diff --git a/microkde/kdecore/kstringhandler.h b/microkde/kdecore/kstringhandler.h
new file mode 100644
index 0000000..d07b1e2
--- a/dev/null
+++ b/microkde/kdecore/kstringhandler.h
@@ -0,0 +1,417 @@
1/* This file is part of the KDE libraries
2 Copyright (C) 1999 Ian Zepp (icszepp@islc.net)
3 Copyright (C) 2000 Rik Hemsley (rikkus) <rik@kde.org>
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License version 2 as published by the Free Software Foundation.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA.
18*/
19#ifndef KSTRINGHANDLER_H
20#define KSTRINGHANDLER_H
21
22#include <stdlib.h> // for atoi()
23#include <qstring.h>
24#include <qstringlist.h>
25#include <qregexp.h> // for the word ranges
26#include <qfontmetrics.h>
27
28/**
29 * This class contains utility functions for handling strings.
30 *
31 * This class is @em not a substitute for the @ref QString class. What
32 * I tried to do with this class is provide an easy way to
33 * cut/slice/splice words inside sentences in whatever order desired.
34 * While the main focus of this class are words (ie characters
35 * separated by spaces/tabs), the two core functions here (@ref split()
36 * and @ref join() ) will function given any char to use as a separator.
37 * This will make it easy to redefine what a 'word' means in the
38 * future if needed.
39 *
40 * I freely stole some of the function names from python. I also think
41 * some of these were influenced by mIRC (yes, believe it if you will, I
42 * used to write a LOT of scripts in mIRC).
43 *
44 * The ranges are a fairly powerful way of getting/stripping words from
45 * a string. These ranges function, for the large part, as they would in
46 * python. See the @ref word(const QString&, int) and @ref remword(const QString&, int) functions for more detail.
47 *
48 * This class contains no data members of it own. All strings are cut
49 * on the fly and returned as new qstrings/qstringlists.
50 *
51 * Quick example on how to use:
52 *
53 * <pre>
54 * KStringHandler kstr;
55 * QString line = "This is a test of the strings";
56 *
57 * cout << "1> " << kstr.word( line , "4:" ) << "\n";
58 * cout << "2> " << kstr.remrange( line , "2:5" ) << "\n";
59 * cout << "2> " << kstr.reverse( line ) << "\n";
60 * cout << "2> " << kstr.center( kstr.word( line , 4 ) , 15 ) << "\n";
61 * </pre>
62 *
63 * and so forth.
64 *
65 * @short Class for manipulating words and sentences in strings
66 * @author Ian Zepp <icszepp@islc.net>
67 */
68class KStringHandler
69{
70public:
71 /** Returns the nth word in the string if found
72 * Returns a EMPTY (not null) string otherwise.
73 * Note that the FIRST index is 0.
74 * @param text the string to search for the words
75 * @param pos the position of the word to search
76 * @return the word, or an empty string if not found
77 */
78//US static QString word( const QString &text , uint pos );
79
80 /** Returns a range of words from that string.
81 * Ie:
82 * @li "0" returns the very first word
83 * @li "0:" returns the first to the last word
84 * @li "0:3" returns the first to fourth words
85 * @li ":3" returns everything up to the fourth word
86 *
87 * If you grok python, you're set.
88 * @param text the string to search for the words
89 * @param range the words to return (see description)
90 * @return the words, or an empty string if not found
91 */
92//US static QString word( const QString &text , const char *range );
93
94 /** Inserts a word into the string, and returns
95 * a new string with the word included. the first
96 * index is zero (0). If there are not @p pos words in the original
97 * string, the new word will be appended to the end.
98 * @param text the original text
99 * @param word the word to insert
100 * @param pos the position (in words) for the new word
101 * @return the resulting string
102 */
103//US static QString insword( const QString &text , const QString &word , uint pos );
104
105 /** Replaces a word in the string, and returns
106 * a new string with the word included. the first
107 * index is zero (0). If there are not @p pos words in the original
108 * string, the new word will be appended to the end.
109 * @param text the original text
110 * @param word the word to insert
111 * @param pos the position (in words) for the new word
112 * @return the resulting string
113 */
114//US static QString setword( const QString &text , const QString &word , uint pos );
115
116 /** Removes a word or ranges of words from the string,
117 * and returns a new string. The ranges definitions
118 * follow the definitions for the word() function.
119 *
120 * @li "0" removes the very first word
121 * @li "0:" removes the first the the last word
122 * @li "0:3" removes the first to fourth words
123 * @li ":3" removes everything up to the fourth word
124 * @param text the original text
125 * @param range the words to remove (see description)
126 * @return the resulting string
127 */
128//US static QString remrange( const QString &text , const char *range );
129
130
131 /** Removes a word at the given index, and returns a
132 * new string. The first index is zero (0).
133 * @param text the original text
134 * @param pos the position (in words) of thw word to delete
135 * @return the resulting string
136 */
137//US static QString remword( const QString &text , uint pos );
138
139 /** Removes a matching word from the string, and returns
140 * a new string. Note that only ONE match is removed.
141 * @param text the original text
142 * @param word the word to remove
143 * @return the resulting string
144 */
145//US static QString remword( const QString &text , const QString &word );
146
147 /** Capitalizes each word in the string
148 * "hello there" becomes "Hello There" (string)
149 * @param text the text to capitalize
150 * @return the resulting string
151 */
152//US static QString capwords( const QString &text );
153
154 /** Capitalizes each word in the list
155 * [hello, there] becomes [Hello, There] (list)
156 * @param list the list to capitalize
157 * @return the resulting list
158 */
159//US static QStringList capwords( const QStringList &list );
160
161 /** Reverses the order of the words in a string
162 * "hello there" becomes "there hello" (string)
163 * @param text the text to reverse
164 * @return the resulting string
165 */
166//US static QString reverse( const QString &text );
167
168 /** Reverses the order of the words in a list
169 * [hello, there] becomes [there, hello] (list)
170 * @param list the list to reverse
171 * @return the resulting list
172 */
173//US static QStringList reverse( const QStringList &list );
174
175 /** Left-justifies a string and returns a string at least 'width' characters
176 * wide.
177 * If the string is longer than the @p width, the original
178 * string is returned. It is never truncated.
179 * @param text the text to justify
180 * @param width the desired width of the new string
181 * @return the resulting string
182 */
183//US static QString ljust( const QString &text , uint width );
184
185 /** Right-justifies a string and returns a string at least 'width' characters
186 * wide.
187 * If the string is longer than the @p width, the original
188 * string is returned. It is never truncated.
189 * @param text the text to justify
190 * @param width the desired width of the new string
191 * @return the resulting string
192 */
193//US static QString rjust( const QString &text , uint width );
194
195 /** Centers a string and returns a string at least 'width' characters
196 * wide.
197 * If the string is longer than the @p width, the original
198 * string is returned. It is never truncated.
199 * @param text the text to justify
200 * @param width the desired width of the new string
201 * @return the resulting string
202 */
203//US static QString center( const QString &text , uint width );
204
205 /** Substitute characters at the beginning of a string by "...".
206 * @param str is the string to modify
207 * @param maxlen is the maximum length the modified string will have
208 * If the original string is shorter than "maxlen", it is returned verbatim
209 * @return the modified string
210 */
211//US static QString lsqueeze( const QString & str, uint maxlen = 40 );
212
213 /** Substitute characters at the beginning of a string by "...". Similar to
214 * method above, except that it truncates based on pixel width rather than
215 * the number of characters
216 * @param name is the string to modify
217 * @param fontMetrics is the font metrics to use to calculate character sizes
218 * @param maxlen is the maximum length in ems the modified string will have
219 * If the original string is shorter than "maxlen", it is returned verbatim
220 * @return the modified string
221 * @since 3.2
222 */
223//US static QString lEmSqueeze( const QString & name,
224//US const QFontMetrics& fontMetrics,
225//US uint maxlen = 30 );
226
227 /** Substitute characters at the beginning of a string by "...". Similar to
228 * method above, except that maxlen is the width in pixels to truncate to
229 * @param name is the string to modify
230 * @param fontMetrics is the font metrics to use to calculate character sizes
231 * @param maxPixels is the maximum pixel length the modified string will have
232 * If the original string is shorter than "maxlen", it is returned verbatim
233 * @return the modified string
234 * @since 3.2
235 */
236//US static QString lPixelSqueeze( const QString & name,
237//US const QFontMetrics& fontMetrics,
238//US uint maxPixels );
239
240 /** Substitute characters at the middle of a string by "...".
241 * @param str is the string to modify
242 * @param maxlen is the maximum length the modified string will have
243 * If the original string is shorter than "maxlen", it is returned verbatim
244 * @return the modified string
245 */
246//US static QString csqueeze( const QString & str, uint maxlen = 40 );
247
248 /** Substitute characters in the middle of a string by "...". Similar to
249 * method above, except that it truncates based on pixel width rather than
250 * the number of characters
251 * @param name is the string to modify
252 * @param fontMetrics is the font metrics to use to calculate character sizes
253 * @param maxlen is the maximum length in ems the modified string will have
254 * If the original string is shorter than "maxlen", it is returned verbatim
255 * @return the modified string
256 * @since 3.2
257 */
258//US static QString cEmSqueeze( const QString & name,
259//US const QFontMetrics& fontMetrics,
260//US uint maxlen = 30 );
261
262 /** Substitute characters in the middle of a string by "...". Similar to
263 * method above, except that maxlen is the width in pixels to truncate to
264 * @param name is the string to modify
265 * @param fontMetrics is the font metrics to use to calculate character sizes
266 * @param maxPixels is the maximum pixel length the modified string will have
267 * If the original string is shorter than "maxlen", it is returned verbatim
268 * @return the modified string
269 * @since 3.2
270 */
271//US static QString cPixelSqueeze( const QString & name,
272//US const QFontMetrics& fontMetrics,
273//US uint maxPixels );
274
275 /** Substitute characters at the end of a string by "...".
276 * @param str is the string to modify
277 * @param maxlen is the maximum length the modified string will have
278 * If the original string is shorter than "maxlen", it is returned verbatim
279 * @return the modified string
280 */
281 static QString rsqueeze( const QString & str, uint maxlen = 40 );
282
283 /** Substitute characters at the end of a string by "...". Similar to
284 * method above, except that it truncates based on pixel width rather than
285 * the number of characters
286 * @param name is the string to modify
287 * @param fontMetrics is the font metrics to use to calculate character sizes
288 * @param maxlen is the maximum length in ems the modified string will have
289 * If the original string is shorter than "maxlen", it is returned verbatim
290 * @return the modified string
291 * @since 3.2
292 */
293//US static QString rEmSqueeze( const QString & name,
294//US const QFontMetrics& fontMetrics,
295//US uint maxlen = 30 );
296
297 /** Substitute characters at the end of a string by "...". Similar to
298 * method above, except that maxlen is the width in pixels to truncate to
299 * @param name is the string to modify
300 * @param fontMetrics is the font metrics to use to calculate character sizes
301 * @param maxPixels is the maximum pixel length the modified string will have
302 * If the original string is shorter than "maxlen", it is returned verbatim
303 * @return the modified string
304 * @since 3.2
305 */
306//US static QString rPixelSqueeze( const QString & name,
307//US const QFontMetrics& fontMetrics,
308//US uint maxPixels );
309
310 /**
311 * Match a filename.
312 * @param filename is the real decoded filename (or dirname
313 * without trailing '/').
314 * @param pattern is a pattern like *.txt, *.tar.gz, Makefile.*, etc.
315 * Patterns with two asterisks like "*.*pk" are not supported.
316 * @return true if the given filename matches the given pattern
317 */
318//US static bool matchFileName( const QString& filename, const QString& pattern );
319
320 /**
321 * Split a QString into a QStringList in a similar fashion to the static
322 * QStringList function in Qt, except you can specify a maximum number
323 * of tokens. If max is specified (!= 0) then only that number of tokens
324 * will be extracted. The final token will be the remainder of the string.
325 *
326 * Example:
327 * <pre>
328 * perlSplit("__", "some__string__for__you__here", 4)
329 * QStringList contains: "some", "string", "for", "you__here"
330 * </pre>
331 *
332 * @param sep is the string to use to delimit s.
333 * @param s is the input string
334 * @param max is the maximum number of extractions to perform, or 0.
335 * @return A QStringList containing tokens extracted from s.
336 */
337//US static QStringList perlSplit
338//US (const QString & sep, const QString & s, uint max = 0);
339
340 /**
341 * Split a QString into a QStringList in a similar fashion to the static
342 * QStringList function in Qt, except you can specify a maximum number
343 * of tokens. If max is specified (!= 0) then only that number of tokens
344 * will be extracted. The final token will be the remainder of the string.
345 *
346 * Example:
347 * <pre>
348 * perlSplit(' ', "kparts reaches the parts other parts can't", 3)
349 * QStringList contains: "kparts", "reaches", "the parts other parts can't"
350 * </pre>
351 *
352 * @param sep is the character to use to delimit s.
353 * @param s is the input string
354 * @param max is the maximum number of extractions to perform, or 0.
355 * @return A QStringList containing tokens extracted from s.
356 */
357//US static QStringList perlSplit
358//US (const QChar & sep, const QString & s, uint max = 0);
359
360 /**
361 * Split a QString into a QStringList in a similar fashion to the static
362 * QStringList function in Qt, except you can specify a maximum number
363 * of tokens. If max is specified (!= 0) then only that number of tokens
364 * will be extracted. The final token will be the remainder of the string.
365 *
366 * Example:
367 * <pre>
368 * perlSplit(QRegExp("[! ]", "Split me up ! I'm bored ! OK ?", 3)
369 * QStringList contains: "Split", "me", "up ! I'm bored, OK ?"
370 * </pre>
371 *
372 * @param sep is the regular expression to use to delimit s.
373 * @param s is the input string
374 * @param max is the maximum number of extractions to perform, or 0.
375 * @return A QStringList containing tokens extracted from s.
376 */
377//US static QStringList perlSplit
378//US (const QRegExp & sep, const QString & s, uint max = 0);
379
380 /**
381 * This method auto-detects URLs in strings, and adds HTML markup to them
382 * so that richtext or HTML-enabled widgets (such as KActiveLabel)
383 * will display the URL correctly.
384 * @param text the string which may contain URLs
385 * @return the resulting text
386 * @since 3.1
387 */
388//US static QString tagURLs( const QString& text );
389
390 /**
391 Obscure string by using a simple symmetric encryption. Applying the
392 function to a string obscured by this function will result in the original
393 string.
394
395 The function can be used to obscure passwords stored to configuration
396 files. Note that this won't give you any more security than preventing
397 that the password is directly copied and pasted.
398
399 @param str string to be obscured
400 @return obscured string
401 @since 3.2
402 */
403 static QString obscure( const QString &str );
404
405#ifdef KDE_NO_COMPAT
406private:
407#endif
408 /**
409 * @deprecated Use @see matchFileName () instead.
410 */
411/*US static bool matchFilename( const QString& filename, const QString& pattern )
412 {
413 return matchFileName (filename, pattern);
414 };
415*/
416};
417#endif
diff --git a/microkde/kdemacros.h b/microkde/kdemacros.h
new file mode 100644
index 0000000..698a15a
--- a/dev/null
+++ b/microkde/kdemacros.h
@@ -0,0 +1,105 @@
1/* This file is part of the KDE libraries
2 Copyright (c) 2002-2003 KDE Team
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA.
18*/
19
20#ifndef _KDE_MACROS_H_
21#define _KDE_MACROS_H_
22
23/**
24 * The KDE_NO_EXPORT macro marks the symbol of the given variable
25 * to be hidden. A hidden symbol is stripped during the linking step,
26 * so it can't be used from outside the resulting library, which is similiar
27 * to static. However, static limits the visibility to the current
28 * compilation unit. hidden symbols can still be used in multiple compilation
29 * units.
30 *
31 * \code
32 * int KDE_NO_EXPORT foo;
33 * int KDE_EXPORT bar;
34 * \end
35 */
36
37#if __GNUC__ - 0 > 3 || (__GNUC__ - 0 == 3 && __GNUC_MINOR__ - 0 > 2)
38#define KDE_NO_EXPORT __attribute__ ((visibility("hidden")))
39#define KDE_EXPORT __attribute__ ((visibility("visible")))
40#else
41#define KDE_NO_EXPORT
42#define KDE_EXPORT
43#endif
44
45/**
46 * The KDE_PACKED can be used to hint the compiler that a particular
47 * structure or class should not contain unnecessary paddings.
48 */
49
50#ifdef __GNUC__
51#define KDE_PACKED __attribute__((__packed__))
52#else
53#define KDE_PACKED
54#endif
55
56/**
57 * The KDE_DEPRECATED macro can be used to trigger compile-time warnings
58 * with gcc >= 3.2 when deprecated functions are used.
59 *
60 * For non-inline functions, the macro gets inserted at the very end of the
61 * function declaration, right before the semicolon:
62 *
63 * \code
64 * DeprecatedConstructor() KDE_DEPRECATED;
65 * void deprecatedFunctionA() KDE_DEPRECATED;
66 * int deprecatedFunctionB() const KDE_DEPRECATED;
67 * \endcode
68 *
69 * Functions which are implemented inline are handled differently: for them,
70 * the KDE_DEPRECATED macro is inserted at the front, right before the return
71 * type, but after "static" or "virtual":
72 *
73 * \code
74 * KDE_DEPRECATED void deprecatedInlineFunctionA() { .. }
75 * virtual KDE_DEPRECATED int deprecatedInlineFunctionB() { .. }
76 * static KDE_DEPRECATED bool deprecatedInlineFunctionC() { .. }
77 * \end
78 *
79 * You can also mark whole structs or classes as deprecated, by inserting the
80 * KDE_DEPRECATED macro after the struct/class keyword, but before the
81 * name of the struct/class:
82 *
83 * \code
84 * class KDE_DEPRECATED DeprecatedClass { };
85 * struct KDE_DEPRECATED DeprecatedStruct { };
86 * \endcode
87 *
88 * \note
89 * It does not make much sense to use the KDE_DEPRECATED keyword for a Qt signal
90 * or a slot; this is because signals and slots always get referenced by the
91 * code generated by moc.
92 *
93 * \par
94 * Also note that it is not possible to use KDE_DEPRECATED for classes which
95 * use the k_dcop keyword (to indicate a DCOP interface declaration); this is
96 * because the dcopidl program would choke on the unexpected declaration
97 * syntax.
98 */
99#if __GNUC__ - 0 > 3 || (__GNUC__ - 0 == 3 && __GNUC_MINOR__ - 0 >= 2)
100# define KDE_DEPRECATED __attribute__ ((deprecated))
101#else
102# define KDE_DEPRECATED
103#endif
104
105#endif // _KDE_MACROS_H_
diff --git a/microkde/kdeui/kaction.cpp b/microkde/kdeui/kaction.cpp
new file mode 100644
index 0000000..77d36a5
--- a/dev/null
+++ b/microkde/kdeui/kaction.cpp
@@ -0,0 +1,1215 @@
1/* This file is part of the KDE libraries
2 Copyright (C) 1999 Reginald Stadlbauer <reggie@kde.org>
3 (C) 1999 Simon Hausmann <hausmann@kde.org>
4 (C) 2000 Nicolas Hadacek <haadcek@kde.org>
5 (C) 2000 Kurt Granroth <granroth@kde.org>
6 (C) 2000 Michael Koch <koch@kde.org>
7 (C) 2001 Holger Freyther <freyther@kde.org>
8 (C) 2002 Ellis Whitehead <ellis@kde.org>
9 (C) 2002 Joseph Wenninger <jowenn@kde.org>
10
11 This library is free software; you can redistribute it and/or
12 modify it under the terms of the GNU Library General Public
13 License version 2 as published by the Free Software Foundation.
14
15 This library is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 Library General Public License for more details.
19
20 You should have received a copy of the GNU Library General Public License
21 along with this library; see the file COPYING.LIB. If not, write to
22 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23 Boston, MA 02111-1307, USA.
24*/
25
26#include "kaction.h"
27
28#include <assert.h>
29
30#include <qtooltip.h>
31//US#include <qwhatsthis.h>
32//US#include <kaccel.h>
33//US#include <kaccelbase.h>
34#include <kapplication.h>
35#include <kdebug.h>
36#include <kguiitem.h>
37//US#include <kmainwindow.h>
38//US#include <kmenubar.h>
39//US#include <kpopupmenu.h>
40#include <ktoolbar.h>
41#include <ktoolbarbutton.h>
42
43//US added this includefiles
44#include <qmenubar.h>
45#include <qtoolbar.h>
46#include <qpopupmenu.h>
47#include <qiconset.h>
48
49/**
50* How it works.
51* KActionCollection is an organizing container for KActions.
52* KActionCollection keeps track of the information necessary to handle
53* configuration and shortcuts.
54*
55* Focus Widget pointer:
56* This is the widget which is the focus for action shortcuts.
57* It is set either by passing a QWidget* to the KActionCollection constructor
58* or by calling setWidget() if the widget wasn't known when the object was
59* initially constructed (as in KXMLGUIClient and KParts::PartBase)
60*
61* Shortcuts:
62* An action's shortcut will not not be connected unless a focus widget has
63* been specified in KActionCollection.
64*
65* XML Filename:
66* This is used to save user-modified settings back to the *ui.rc file.
67* It is set by KXMLGUIFactory.
68*/
69
70int KAction::getToolButtonID()
71{
72 static int toolbutton_no = -2;
73 return toolbutton_no--;
74}
75
76//---------------------------------------------------------------------
77// KAction::KActionPrivate
78//---------------------------------------------------------------------
79
80class KAction::KActionPrivate : public KGuiItem
81{
82public:
83 KActionPrivate() : KGuiItem()
84 {
85 m_kaccel = 0;
86 m_configurable = true;
87 }
88
89 KAccel *m_kaccel;
90 QValueList<KAccel*> m_kaccelList;
91
92 QString m_groupText;
93 QString m_group;
94
95 KShortcut m_cut;
96 KShortcut m_cutDefault;
97
98 bool m_configurable;
99
100 struct Container
101 {
102 Container() { m_container = 0; m_representative = 0; m_id = 0; }
103 Container( const Container& s ) { m_container = s.m_container;
104 m_id = s.m_id; m_representative = s.m_representative; }
105 QWidget* m_container;
106 int m_id;
107 QWidget* m_representative;
108 };
109
110 QValueList<Container> m_containers;
111};
112
113//---------------------------------------------------------------------
114// KAction
115//---------------------------------------------------------------------
116KAction::KAction( const QString& text, const KShortcut& cut,
117 const QObject* receiver, const char* slot,
118 KActionCollection* parent, const char* name )
119: QObject( parent, name )
120{
121 initPrivate( text, cut, receiver, slot );
122}
123
124KAction::KAction( const QString& text, const QString& sIconName, const KShortcut& cut,
125 const QObject* receiver, const char* slot,
126 KActionCollection* parent, const char* name )
127: QObject( parent, name )
128{
129 initPrivate( text, cut, receiver, slot );
130 d->setIconName( sIconName );
131}
132
133KAction::KAction( const QString& text, const QIconSet& pix, const KShortcut& cut,
134 const QObject* receiver, const char* slot,
135 KActionCollection* parent, const char* name )
136: QObject( parent, name )
137{
138 initPrivate( text, cut, receiver, slot );
139 d->setIconSet( pix );
140}
141KAction::KAction( const KGuiItem& item, const KShortcut& cut,
142 const QObject* receiver, const char* slot,
143 KActionCollection* parent, const char* name )
144: QObject( parent, name )
145{
146 initPrivate( item.text(), cut, receiver, slot );
147 if( item.hasIconSet() )
148 setIcon( item.iconName() );
149 setToolTip( item.toolTip() );
150 setWhatsThis( item.whatsThis() );
151}
152
153// KDE 4: remove
154KAction::KAction( const QString& text, const KShortcut& cut,
155 QObject* parent, const char* name )
156 : QObject( parent, name )
157{
158 initPrivate( text, cut, 0, 0 );
159}
160KAction::KAction( const QString& text, const KShortcut& cut,
161 const QObject* receiver,
162 const char* slot, QObject* parent, const char* name )
163 : QObject( parent, name )
164{
165 initPrivate( text, cut, receiver, slot );
166}
167KAction::KAction( const QString& text, const QIconSet& pix,
168 const KShortcut& cut,
169 QObject* parent, const char* name )
170 : QObject( parent, name )
171{
172 initPrivate( text, cut, 0, 0 );
173 setIconSet( pix );
174}
175
176KAction::KAction( const QString& text, const QString& pix,
177 const KShortcut& cut,
178 QObject* parent, const char* name )
179: QObject( parent, name )
180{
181 initPrivate( text, cut, 0, 0 );
182 d->setIconName( pix );
183}
184
185KAction::KAction( const QString& text, const QIconSet& pix,
186 const KShortcut& cut,
187 const QObject* receiver, const char* slot, QObject* parent,
188 const char* name )
189 : QObject( parent, name )
190{
191 initPrivate( text, cut, receiver, slot );
192 setIconSet( pix );
193}
194
195KAction::KAction( const QString& text, const QString& pix,
196 const KShortcut& cut,
197 const QObject* receiver, const char* slot, QObject* parent,
198 const char* name )
199 : QObject( parent, name )
200{
201 initPrivate( text, cut, receiver, slot );
202 d->setIconName(pix);
203}
204
205KAction::KAction( QObject* parent, const char* name )
206 : QObject( parent, name )
207{
208
209 initPrivate( QString::null, KShortcut(), 0, 0 );
210}
211// KDE 4: remove end
212
213KAction::~KAction()
214{
215 kdDebug(129) << "KAction::~KAction( this = \"" << name() << "\" )" << endl; // -- ellis
216#ifndef KDE_NO_COMPAT
217 if (d->m_kaccel)
218 unplugAccel();
219#endif
220
221 // If actionCollection hasn't already been destructed,
222 if ( m_parentCollection ) {
223 m_parentCollection->take( this );
224 for( uint i = 0; i < d->m_kaccelList.count(); i++ )
225//US d->m_kaccelList[i]->remove( name() );
226 qDebug("KAction::KAction~ ...1 has top be fixed");
227 }
228
229 // Do not call unplugAll from here, as tempting as it sounds.
230 // KAction is designed around the idea that you need to plug
231 // _and_ to unplug it "manually". Unplugging leads to an important
232 // slowdown when e.g. closing the window, in which case we simply
233 // want to destroy everything asap, not to remove actions one by one
234 // from the GUI.
235
236 delete d; d = 0;
237}
238
239void KAction::initPrivate( const QString& text, const KShortcut& cut,
240 const QObject* receiver, const char* slot )
241{
242 d = new KActionPrivate;
243
244 d->m_cutDefault = cut;
245
246//US m_parentCollection = dynamic_cast<KActionCollection *>( parent() );
247 m_parentCollection = (KActionCollection *)( parent() );
248 kdDebug(129) << "KAction::initPrivate(): this = " << this << " name = \"" << name() << "\" cut = " << cut.toStringInternal() << " m_parentCollection = " << m_parentCollection << endl;
249 if ( m_parentCollection )
250 m_parentCollection->insert( this );
251
252 if ( receiver && slot )
253 connect( this, SIGNAL( activated() ), receiver, slot );
254
255 if( !cut.isNull() && qstrcmp( name(), "unnamed" ) == 0 )
256 kdWarning(129) << "KAction::initPrivate(): trying to assign a shortcut (" << cut.toStringInternal() << ") to an unnamed action." << endl;
257 d->setText( text );
258 initShortcut( cut );
259
260}
261
262bool KAction::isPlugged() const
263{
264 return (containerCount() > 0) || d->m_kaccel;
265}
266
267bool KAction::isPlugged( const QWidget *container ) const
268{
269 return findContainer( container ) > -1;
270}
271
272bool KAction::isPlugged( const QWidget *container, int id ) const
273{
274 int i = findContainer( container );
275 return ( i > -1 && itemId( i ) == id );
276}
277
278bool KAction::isPlugged( const QWidget *container, const QWidget *_representative ) const
279{
280 int i = findContainer( container );
281 return ( i > -1 && representative( i ) == _representative );
282}
283
284
285/*
286Three actionCollection conditions:
287 1) Scope is known on creation and KAccel object is created (e.g. KMainWindow)
288 2) Scope is unknown and no KAccel object is available (e.g. KXMLGUIClient)
289 a) addClient() will be called on object
290 b) we just want to add the actions to another KXMLGUIClient object
291
292The question is how to do we incorporate #2b into the XMLGUI framework?
293
294
295We have a KCommandHistory object with undo and redo actions in a passed actionCollection
296We have a KoDoc object which holds a KCommandHistory object and the actionCollection
297We have two KoView objects which both point to the same KoDoc object
298Undo and Redo should be available in both KoView objects, and
299 calling the undo->setEnabled() should affect both KoViews
300
301When addClient is called, it needs to be able to find the undo and redo actions
302When it calls plug() on them, they need to be inserted into the KAccel object of the appropriate KoView
303
304In this case, the actionCollection belongs to KoDoc and we need to let it know that its shortcuts
305have the same scope as the KoView actionCollection
306
307KXMLGUIClient::addSubActionCollection
308
309Document:
310 create document actions
311
312View
313 create view actions
314 add document actionCollection as sub-collection
315
316A parentCollection is created
317Scenario 1: parentCollection has a focus widget set (e.g. via KMainWindow)
318 A KAccel object is created in the parentCollection
319 A KAction is created with parent=parentCollection
320 The shortcut is inserted into this actionCollection
321 Scenario 1a: xml isn't used
322 done
323 Scenario 1b: KXMLGUIBuilder::addClient() called
324 setWidget is called -- ignore
325 shortcuts are set
326Scenario 2: parentCollection has no focus widget (e.g., KParts)
327 A KAction is created with parent=parentCollection
328 Scenario 2a: xml isn't used
329 no shortcuts
330 Scenario 2b: KXMLGUIBuilder::addClient() called
331 setWidget is called
332 shortcuts are inserted into current KAccel
333 shortcuts are set in all other KAccels, if the action is present in the other KAccels
334*/
335
336/*
337shortcut may be set:
338 - on construction
339 - on plug
340 - on reading XML
341 - on plugAccel (deprecated)
342
343On Construction: [via initShortcut()]
344 insert into KAccel of m_parentCollection,
345 if kaccel() && isAutoConnectShortcuts() exists
346
347On Plug: [via plug() -> plugShortcut()]
348 insert into KAccel of m_parentCollection, if exists and not already inserted into
349
350On Read XML: [via setShortcut()]
351 set in all current KAccels
352 insert into KAccel of m_parentCollection, if exists and not already inserted into
353*/
354
355KAccel* KAction::kaccelCurrent()
356{
357 if( m_parentCollection && m_parentCollection->builderKAccel() )
358 return m_parentCollection->builderKAccel();
359 else if( m_parentCollection && m_parentCollection->kaccel() )
360 return m_parentCollection->kaccel();
361 else
362 return 0L;
363}
364
365// Only to be called from initPrivate()
366bool KAction::initShortcut( const KShortcut& cut )
367{
368 d->m_cut = cut;
369
370 // Only insert action into KAccel if it has a valid name,
371 if( qstrcmp( name(), "unnamed" ) != 0 &&
372 m_parentCollection &&
373 m_parentCollection->isAutoConnectShortcuts() &&
374 m_parentCollection->kaccel() )
375 {
376 insertKAccel( m_parentCollection->kaccel() );
377 return true;
378 }
379 return false;
380 }
381
382// Only to be called from plug()
383void KAction::plugShortcut()
384{
385 KAccel* kaccel = kaccelCurrent();
386
387 //kdDebug(129) << "KAction::plugShortcut(): this = " << this << " kaccel() = " << (m_parentCollection ? m_parentCollection->kaccel() : 0) << endl;
388 if( kaccel && qstrcmp( name(), "unnamed" ) != 0 ) {
389 // Check if already plugged into current KAccel object
390 for( uint i = 0; i < d->m_kaccelList.count(); i++ ) {
391 if( d->m_kaccelList[i] == kaccel )
392 return;
393 }
394
395 insertKAccel( kaccel );
396 }
397}
398
399bool KAction::setShortcut( const KShortcut& cut )
400{
401 qDebug("KAction::setShortcut~ ...1 has top be fixed");
402/*US
403 bool bChanged = (d->m_cut != cut);
404 d->m_cut = cut;
405
406 KAccel* kaccel = kaccelCurrent();
407 bool bInsertRequired = true;
408 // Apply new shortcut to all existing KAccel objects
409 for( uint i = 0; i < d->m_kaccelList.count(); i++ ) {
410 // Check whether shortcut has already been plugged into
411 // the current kaccel object.
412 if( d->m_kaccelList[i] == kaccel )
413 bInsertRequired = false;
414 if( bChanged )
415 updateKAccelShortcut( d->m_kaccelList[i] );
416 }
417
418 // Only insert action into KAccel if it has a valid name,
419 if( kaccel && bInsertRequired && qstrcmp( name(), "unnamed" ) )
420 insertKAccel( kaccel );
421
422 if( bChanged ) {
423 // KDE 4: remove
424 if ( d->m_kaccel )
425 d->m_kaccel->setShortcut( name(), cut );
426 // KDE 4: remove end
427 int len = containerCount();
428 for( int i = 0; i < len; ++i )
429 updateShortcut( i );
430 }
431*/
432
433 return true;
434}
435
436bool KAction::updateKAccelShortcut( KAccel* kaccel )
437{
438 qDebug("KAction::updateKAccelShortcut~ ...1 has top be fixed");
439 // Check if action is permitted
440/*US
441 if (kapp && !kapp->authorizeKAction(name()))
442 return false;
443
444 bool b = true;
445
446 if ( !kaccel->actions().actionPtr( name() ) ) {
447 if(!d->m_cut.isNull() ) {
448 kdDebug(129) << "Inserting " << name() << ", " << d->text() << ", " << d->plainText() << endl;
449 b = kaccel->insert( name(), d->plainText(), QString::null,
450 d->m_cut,
451 this, SLOT(slotActivated()),
452 isShortcutConfigurable(), isEnabled() );
453 }
454 }
455 else
456 b = kaccel->setShortcut( name(), d->m_cut );
457
458 return b;
459*/
460 return true;
461}
462
463void KAction::insertKAccel( KAccel* kaccel )
464{
465 qDebug("KAction::updateKAccelShortcut~ ...1 has top be fixed");
466/*US
467 //kdDebug(129) << "KAction::insertKAccel( " << kaccel << " ): this = " << this << endl;
468 if ( !kaccel->actions().actionPtr( name() ) ) {
469 if( updateKAccelShortcut( kaccel ) ) {
470 d->m_kaccelList.append( kaccel );
471 connect( kaccel, SIGNAL(destroyed()), this, SLOT(slotDestroyed()) );
472 }
473 }
474 else
475 kdWarning(129) << "KAction::insertKAccel( kaccel = " << kaccel << " ): KAccel object already contains an action name \"" << name() << "\"" << endl; // -- ellis
476*/
477}
478
479void KAction::removeKAccel( KAccel* kaccel )
480{
481 qDebug("KAction::removeKAccel~ ...1 has top be fixed");
482/*US
483 //kdDebug(129) << "KAction::removeKAccel( " << i << " ): this = " << this << endl;
484 for( uint i = 0; i < d->m_kaccelList.count(); i++ ) {
485 if( d->m_kaccelList[i] == kaccel ) {
486 kaccel->remove( name() );
487 d->m_kaccelList.remove( d->m_kaccelList.at( i ) );
488 disconnect( kaccel, SIGNAL(destroyed()), this, SLOT(slotDestroyed()) );
489 break;
490 }
491 }
492*/
493}
494
495// KDE 4: remove
496void KAction::setAccel( int keyQt )
497{
498 setShortcut( KShortcut(keyQt) );
499}
500// KDE 4: remove end
501
502void KAction::updateShortcut( int i )
503{
504 int id = itemId( i );
505
506 QWidget* w = container( i );
507 if ( w->inherits( "QPopupMenu" ) ) {
508 QPopupMenu* menu = static_cast<QPopupMenu*>(w);
509 updateShortcut( menu, id );
510 }
511 else if ( w->inherits( "QMenuBar" ) )
512//US static_cast<QMenuBar*>(w)->setAccel( d->m_cut.keyCodeQt(), id );
513//US (QMenuBar*)(w)->setAccel( d->m_cut.keyCodeQt(), id );
514 qDebug("KAction::updateShortcut( int i ) ...1 has top be fixed");
515
516}
517
518void KAction::updateShortcut( QPopupMenu* menu, int id )
519{
520/*US
521 //kdDebug(129) << "KAction::updateShortcut(): this = " << this << " d->m_kaccelList.count() = " << d->m_kaccelList.count() << endl;
522 // If the action has a KAccel object,
523 // show the string representation of its shortcut.
524 if ( d->m_kaccel || d->m_kaccelList.count() ) {
525 QString s = menu->text( id );
526 int i = s.find( '\t' );
527 if ( i >= 0 )
528 s.replace( i+1, s.length()-i, d->m_cut.seq(0).toString() );
529 else
530 s += "\t" + d->m_cut.seq(0).toString();
531
532 menu->changeItem( id, s );
533 }
534 // Otherwise insert the shortcut itself into the popup menu.
535 else {
536 // This is a fall-hack in case the KAction is missing a proper parent collection.
537 // It should be removed eventually. --ellis
538 menu->setAccel( d->m_cut.keyCodeQt(), id );
539 kdWarning(129) << "KAction::updateShortcut(): name = \"" << name() << "\", cut = " << d->m_cut.toStringInternal() << "; No KAccel, probably missing a parent collection." << endl;
540 }
541*/
542 qDebug("KAction::updateShortcut( QPopupMenu* menu, int id ) ...1 has top be fixed");
543
544}
545
546const KShortcut& KAction::shortcut() const
547{
548 return d->m_cut;
549}
550
551const KShortcut& KAction::shortcutDefault() const
552{
553 return d->m_cutDefault;
554}
555
556QString KAction::shortcutText() const
557{
558 return d->m_cut.toStringInternal();
559}
560
561void KAction::setShortcutText( const QString& s )
562{
563 setShortcut( KShortcut(s) );
564}
565
566int KAction::accel() const
567{
568 qDebug("KAction::accel() ...1 has top be fixed");
569//US return d->m_cut.keyCodeQt();
570 return 0;
571}
572
573void KAction::setGroup( const QString& grp )
574{
575 d->m_group = grp;
576
577 int len = containerCount();
578 for( int i = 0; i < len; ++i )
579 updateGroup( i );
580}
581
582void KAction::updateGroup( int )
583{
584 // DO SOMETHING
585}
586
587QString KAction::group() const
588{
589 return d->m_group;
590}
591
592bool KAction::isEnabled() const
593{
594 return d->isEnabled();
595}
596
597bool KAction::isShortcutConfigurable() const
598{
599 return d->m_configurable;
600}
601
602void KAction::setToolTip( const QString& tt )
603{
604 qDebug("KAction::setToolTip ...1 has top be fixed");
605 d->setToolTip( tt );
606
607 int len = containerCount();
608 for( int i = 0; i < len; ++i )
609 updateToolTip( i );
610}
611
612void KAction::updateToolTip( int i )
613{
614 qDebug("KAction::updateToolTip ...1 has top be fixed");
615 QWidget *w = container( i );
616
617 if ( w->inherits( "KToolBar" ) )
618 QToolTip::add( static_cast<KToolBar*>(w)->getWidget( itemId( i ) ), d->toolTip() );
619 else if ( w->inherits( "QToolBar" ) )
620 QToolTip::add( static_cast<KToolBar*>(w)->getWidget( itemId( i ) ), d->toolTip() );
621}
622
623QString KAction::toolTip() const
624{
625 return d->toolTip();
626}
627
628int KAction::plug( QWidget *w, int index )
629{
630 //kdDebug(129) << "KAction::plug( " << w << ", " << index << " )" << endl;
631 if (w == 0) {
632 kdWarning(129) << "KAction::plug called with 0 argument\n";
633 return -1;
634 }
635
636#ifndef NDEBUG
637 KAccel* kaccel = kaccelCurrent();
638 // If there is a shortcut, but no KAccel available
639 if( !d->m_cut.isNull() && kaccel == 0 ) {
640 kdWarning(129) << "KAction::plug(): has no KAccel object; this = " << this << " name = " << name() << " parentCollection = " << m_parentCollection << endl; // ellis
641//US kdDebug(129) << kdBacktrace() << endl;
642 }
643#endif
644
645 // Check if action is permitted
646//US if (kapp && !kapp->authorizeKAction(name()))
647//US return -1;
648
649 plugShortcut();
650
651 if ( w->inherits("QPopupMenu") )
652 {
653 QPopupMenu* menu = static_cast<QPopupMenu*>( w );
654 int id;
655 // Don't insert shortcut into menu if it's already in a KAccel object.
656 //qDebug("KAction::plug warning: real shortcuts not available yet. ");
657//US int keyQt = (d->m_kaccelList.count() || d->m_kaccel) ? 0 : d->m_cut.keyCodeQt();
658 int keyQt = 0;
659
660 if ( d->hasIcon() )
661 {
662/*US
663 KInstance *instance;
664 if ( m_parentCollection )
665 instance = m_parentCollection->instance();
666 else
667 instance = KGlobal::instance();
668*/
669 id = menu->insertItem( d->iconSet( KIcon::Small, 0/*US , instance */), d->text(), this,//dsweet
670 SLOT( slotActivated() ), keyQt,
671 -1, index );
672 }
673 else
674 id = menu->insertItem( d->text(), this,
675 SLOT( slotActivated() ), //dsweet
676 keyQt, -1, index );
677
678 // If the shortcut is already in a KAccel object, then
679 // we need to set the menu item's shortcut text.
680/*US if ( d->m_kaccelList.count() || d->m_kaccel )
681 updateShortcut( menu, id );
682*/
683 // call setItemEnabled only if the item really should be disabled,
684 // because that method is slow and the item is per default enabled
685 if ( !d->isEnabled() )
686 menu->setItemEnabled( id, false );
687
688 if ( !d->whatsThis().isEmpty() )
689 menu->setWhatsThis( id, whatsThisWithIcon() );
690
691 addContainer( menu, id );
692 connect( menu, SIGNAL( destroyed() ), this, SLOT( slotDestroyed() ) );
693
694 if ( m_parentCollection )
695 m_parentCollection->connectHighlight( menu, this );
696
697 return d->m_containers.count() - 1;
698 }
699 else if ( w->inherits( "KToolBar" ) )
700 {
701 KToolBar *bar = static_cast<KToolBar *>( w );
702
703 int id_ = getToolButtonID();
704/*US
705 KInstance *instance;
706 if ( m_parentCollection )
707 instance = m_parentCollection->instance();
708 else
709 instance = KGlobal::instance();
710*/
711 if ( icon().isEmpty() && !iconSet().pixmap().isNull() ) // old code using QIconSet directly
712 {
713 bar->insertButton( iconSet().pixmap(), id_, SIGNAL( clicked() ), this,
714 SLOT( slotActivated() ),
715 d->isEnabled(), d->plainText(), index );
716 }
717 else
718 {
719 QString icon = d->iconName();
720 if ( icon.isEmpty() )
721 icon = "unknown";
722 bar->insertButton( icon, id_, SIGNAL( clicked() ), this,
723 SLOT( slotActivated() ),
724 d->isEnabled(), d->plainText(), index/*US, instance*/ );
725 }
726 bar->getButton( id_ )->setName( QCString("toolbutton_")+name() );
727
728//US if ( !d->whatsThis().isEmpty() )
729//US QWhatsThis::add( bar->getButton(id_), whatsThisWithIcon() );
730 if ( !d->toolTip().isEmpty() )
731 QToolTip::add( bar->getButton(id_), d->toolTip() );
732
733 addContainer( bar, id_ );
734
735 connect( bar, SIGNAL( destroyed() ), this, SLOT( slotDestroyed() ) );
736
737 if ( m_parentCollection )
738 m_parentCollection->connectHighlight( bar, this );
739
740 return containerCount() - 1;
741
742 }
743
744 return -1;
745}
746
747void KAction::unplug( QWidget *w )
748{
749 int i = findContainer( w );
750 if ( i == -1 )
751 return;
752 int id = itemId( i );
753
754 if ( w->inherits( "QPopupMenu" ) )
755 {
756 QPopupMenu *menu = static_cast<QPopupMenu *>( w );
757 menu->removeItem( id );
758 }
759 else if ( w->inherits( "KToolBar" ) )
760 {
761 KToolBar *bar = static_cast<KToolBar *>( w );
762 bar->removeItemDelayed( id );
763 }
764 else if ( w->inherits( "QMenuBar" ) )
765 {
766 QMenuBar *bar = static_cast<QMenuBar *>( w );
767 bar->removeItem( id );
768 }
769
770 removeContainer( i );
771
772 if ( m_parentCollection )
773 m_parentCollection->disconnectHighlight( w, this );
774}
775
776void KAction::plugAccel(KAccel *kacc, bool configurable)
777{
778 qDebug("KAction::plugAccel ...1 has top be fixed");
779/*US
780 kdWarning(129) << "KAction::plugAccel(): call to deprecated action." << endl;
781 kdDebug(129) << kdBacktrace() << endl;
782 //kdDebug(129) << "KAction::plugAccel( kacc = " << kacc << " ): name \"" << name() << "\"" << endl;
783 if ( d->m_kaccel )
784 unplugAccel();
785
786 // If the parent collection's accel ptr isn't set yet
787 //if ( m_parentCollection && !m_parentCollection->accel() )
788 // m_parentCollection->setAccel( kacc );
789
790 // We can only plug this action into the given KAccel object
791 // if it does not already contain an action with the same name.
792 if ( !kacc->actions().actionPtr(name()) )
793 {
794 d->m_kaccel = kacc;
795 d->m_kaccel->insert(name(), d->plainText(), QString::null,
796 KShortcut(d->m_cut),
797 this, SLOT(slotActivated()),
798 configurable, isEnabled());
799 connect(d->m_kaccel, SIGNAL(destroyed()), this, SLOT(slotDestroyed()));
800 //connect(d->m_kaccel, SIGNAL(keycodeChanged()), this, SLOT(slotKeycodeChanged()));
801 }
802 else
803 kdWarning(129) << "KAction::plugAccel( kacc = " << kacc << " ): KAccel object already contains an action name \"" << name() << "\"" << endl; // -- ellis
804*/
805}
806
807void KAction::unplugAccel()
808{
809 qDebug("KAction::unplugAccel ...1 has top be fixed");
810/*US
811 //kdDebug(129) << "KAction::unplugAccel() " << this << " " << name() << endl;
812 if ( d->m_kaccel )
813 {
814 d->m_kaccel->remove(name());
815 d->m_kaccel = 0;
816 }
817*/
818}
819
820void KAction::plugMainWindowAccel( QWidget *w )
821{
822 qDebug("KAction::plugMainWindowAccel ...1 has top be fixed");
823/*US
824 // Note: topLevelWidget() stops too early, we can't use it.
825 QWidget * tl = w;
826 QWidget * n;
827 while ( !tl->isDialog() && ( n = tl->parentWidget() ) ) // lookup parent and store
828 tl = n;
829
830 KMainWindow * mw = dynamic_cast<KMainWindow *>(tl); // try to see if it's a kmainwindow
831 if (mw)
832 plugAccel( mw->accel() );
833 else
834 kdDebug(129) << "KAction::plugMainWindowAccel: Toplevel widget isn't a KMainWindow, can't plug accel. " << tl << endl;
835*/
836}
837
838void KAction::setEnabled(bool enable)
839{
840 //kdDebug(129) << "KAction::setEnabled( " << enable << " ): this = " << this << " d->m_kaccelList.count() = " << d->m_kaccelList.count() << endl;
841 if ( enable == d->isEnabled() )
842 return;
843
844 // KDE 4: remove
845//US if (d->m_kaccel)
846//US d->m_kaccel->setEnabled(name(), enable);
847 // KDE 4: remove end
848
849//US for ( uint i = 0; i < d->m_kaccelList.count(); i++ )
850//US d->m_kaccelList[i]->setEnabled( name(), enable );
851
852 d->setEnabled( enable );
853
854 int len = containerCount();
855 for( int i = 0; i < len; ++i )
856 updateEnabled( i );
857
858 emit enabled( d->isEnabled() );
859}
860
861void KAction::updateEnabled( int i )
862{
863 QWidget *w = container( i );
864
865 if ( w->inherits("QPopupMenu") )
866 static_cast<QPopupMenu*>(w)->setItemEnabled( itemId( i ), d->isEnabled() );
867 else if ( w->inherits("QMenuBar") )
868 static_cast<QMenuBar*>(w)->setItemEnabled( itemId( i ), d->isEnabled() );
869 else if ( w->inherits( "KToolBar" ) )
870 {
871 static_cast<KToolBar*>(w)->setItemEnabled( itemId( i ), d->isEnabled() );
872 }
873}
874
875void KAction::setShortcutConfigurable( bool b )
876{
877 d->m_configurable = b;
878}
879
880void KAction::setText( const QString& text )
881{
882/*US
883 // KDE 4: remove
884 if (d->m_kaccel) {
885 KAccelAction* pAction = d->m_kaccel->actions().actionPtr(name());
886 if (pAction)
887 pAction->setLabel( text );
888 }
889 // KDE 4: remove end
890
891 for( uint i = 0; i < d->m_kaccelList.count(); i++ ) {
892 KAccelAction* pAction = d->m_kaccelList[i]->actions().actionPtr(name());
893 if (pAction)
894 pAction->setLabel( text );
895 }
896*/
897 d->setText( text );
898
899 int len = containerCount();
900 for( int i = 0; i < len; ++i )
901 updateText( i );
902
903}
904
905void KAction::updateText( int i )
906{
907 QWidget *w = container( i );
908
909 if ( w->inherits( "QPopupMenu" ) ) {
910 int id = itemId( i );
911 static_cast<QPopupMenu*>(w)->changeItem( id, d->text() );
912 updateShortcut( static_cast<QPopupMenu*>(w), id );
913 }
914 else if ( w->inherits( "QMenuBar" ) )
915 static_cast<QMenuBar*>(w)->changeItem( itemId( i ), d->text() );
916 else if ( w->inherits( "KToolBar" ) )
917 {
918 qDebug("KAction::updateText ...3 has top be fixed");
919 QWidget *button = static_cast<KToolBar *>(w)->getWidget( itemId( i ) );
920 if ( button->inherits( "KToolBarButton" ) )
921 static_cast<KToolBarButton *>(button)->setText( d->plainText() );
922
923 }
924}
925
926QString KAction::text() const
927{
928 return d->text();
929}
930
931QString KAction::plainText() const
932{
933 return d->plainText( );
934}
935
936void KAction::setIcon( const QString &icon )
937{
938 d->setIconName( icon );
939
940 // now handle any toolbars
941 int len = containerCount();
942 for ( int i = 0; i < len; ++i )
943 updateIcon( i );
944}
945
946void KAction::updateIcon( int id )
947{
948 QWidget* w = container( id );
949
950 if ( w->inherits( "QPopupMenu" ) ) {
951 int itemId_ = itemId( id );
952 static_cast<QPopupMenu*>(w)->changeItem( itemId_, d->iconSet( KIcon::Small ), d->text() );
953 updateShortcut( static_cast<QPopupMenu*>(w), itemId_ );
954 }
955 else if ( w->inherits( "QMenuBar" ) )
956 static_cast<QMenuBar*>(w)->changeItem( itemId( id ), d->iconSet( KIcon::Small ), d->text() );
957 else if ( w->inherits( "KToolBar" ) )
958 static_cast<KToolBar *>(w)->setButtonIcon( itemId( id ), d->iconName() );
959 else if ( w->inherits( "QToolBar" ) )
960 {
961 qDebug("KAction::updateIcon has top be fixed");
962//US static_cast<QToolBar *>(w)->setButtonIcon( itemId( id ), d->iconName() );
963 }
964}
965
966QString KAction::icon() const
967{
968 return d->iconName( );
969}
970
971void KAction::setIconSet( const QIconSet &iconset )
972{
973 d->setIconSet( iconset );
974
975 int len = containerCount();
976 for( int i = 0; i < len; ++i )
977 updateIconSet( i );
978}
979
980
981void KAction::updateIconSet( int id )
982{
983 QWidget *w = container( id );
984
985 if ( w->inherits( "QPopupMenu" ) )
986 {
987 int itemId_ = itemId( id );
988 static_cast<QPopupMenu*>(w)->changeItem( itemId_, d->iconSet(), d->text() );
989 updateShortcut( static_cast<QPopupMenu*>(w), itemId_ );
990 }
991 else if ( w->inherits( "QMenuBar" ) )
992 static_cast<QMenuBar*>(w)->changeItem( itemId( id ), d->iconSet(), d->text() );
993 else if ( w->inherits( "KToolBar" ) )
994 {
995 if ( icon().isEmpty() && d->hasIconSet() ) // only if there is no named icon ( scales better )
996 static_cast<KToolBar *>(w)->setButtonIconSet( itemId( id ), d->iconSet() );
997 else
998 static_cast<KToolBar *>(w)->setButtonIconSet( itemId( id ), d->iconSet( KIcon::Small ) );
999 }
1000}
1001
1002QIconSet KAction::iconSet( KIcon::Group group, int size ) const
1003{
1004 return d->iconSet( group, size );
1005}
1006
1007bool KAction::hasIcon() const
1008{
1009 return d->hasIcon();
1010}
1011
1012
1013void KAction::setWhatsThis( const QString& text )
1014{
1015 d->setWhatsThis( text );
1016
1017 int len = containerCount();
1018 for( int i = 0; i < len; ++i )
1019 updateWhatsThis( i );
1020}
1021
1022void KAction::updateWhatsThis( int i )
1023{
1024 qDebug("KAction::updateWhatsThis ...1 has top be fixed");
1025 QPopupMenu* pm = popupMenu( i );
1026 if ( pm )
1027 {
1028 pm->setWhatsThis( itemId( i ), d->whatsThis() );
1029 return;
1030 }
1031
1032 KToolBar *tb = toolBar( i );
1033 if ( tb )
1034 {
1035 QWidget *w = tb->getButton( itemId( i ) );
1036//US QWhatsThis::remove( w );
1037//US QWhatsThis::add( w, d->whatsThis() );
1038 return;
1039 }
1040}
1041
1042QString KAction::whatsThis() const
1043{
1044 return d->whatsThis();
1045}
1046
1047QString KAction::whatsThisWithIcon() const
1048{
1049 QString text = whatsThis();
1050 if (!d->iconName().isEmpty())
1051 return QString::fromLatin1("<img source=\"small|%1\"> %2").arg(d->iconName() ).arg(text);
1052 return text;
1053}
1054
1055QWidget* KAction::container( int index ) const
1056{
1057 assert( index < containerCount() );
1058 return d->m_containers[ index ].m_container;
1059}
1060
1061KToolBar* KAction::toolBar( int index ) const
1062{
1063//US return dynamic_cast<KToolBar *>( d->m_containers[ index ].m_container );
1064 return (KToolBar *)( d->m_containers[ index ].m_container );
1065}
1066
1067QPopupMenu* KAction::popupMenu( int index ) const
1068{
1069//US return dynamic_cast<QPopupMenu *>( d->m_containers[ index ].m_container );
1070 return (QPopupMenu *)( d->m_containers[ index ].m_container );
1071}
1072
1073QWidget* KAction::representative( int index ) const
1074{
1075 return d->m_containers[ index ].m_representative;
1076}
1077
1078int KAction::itemId( int index ) const
1079{
1080 return d->m_containers[ index ].m_id;
1081}
1082
1083int KAction::containerCount() const
1084{
1085 return d->m_containers.count();
1086}
1087
1088uint KAction::kaccelCount() const
1089{
1090 return d->m_kaccelList.count();
1091}
1092
1093void KAction::addContainer( QWidget* c, int id )
1094{
1095 KActionPrivate::Container p;
1096 p.m_container = c;
1097 p.m_id = id;
1098 d->m_containers.append( p );
1099}
1100
1101void KAction::addContainer( QWidget* c, QWidget* w )
1102{
1103 KActionPrivate::Container p;
1104 p.m_container = c;
1105 p.m_representative = w;
1106 d->m_containers.append( p );
1107}
1108
1109void KAction::activate()
1110{
1111 slotActivated();
1112}
1113
1114void KAction::slotActivated()
1115{
1116 emit activated();
1117}
1118
1119void KAction::slotDestroyed()
1120{
1121 kdDebug(129) << "KAction::slotDestroyed(): this = " << this << ", name = \"" << name() << "\", sender = " << sender() << endl;
1122 const QObject* o = sender();
1123
1124/*
1125
1126
1127 // KDE 4: remove
1128 if ( o == d->m_kaccel )
1129 {
1130 d->m_kaccel = 0;
1131 return;
1132 }
1133 // KDE 4: remove end
1134
1135 for( uint i = 0; i < d->m_kaccelList.count(); i++ )
1136 {
1137 if ( o == d->m_kaccelList[i] )
1138 {
1139 disconnect( d->m_kaccelList[i], SIGNAL(destroyed()), this, SLOT(slotDestroyed()) );
1140 d->m_kaccelList.remove( d->m_kaccelList.at( i ) );
1141 return;
1142 }
1143 }
1144*/
1145 int i;
1146 do
1147 {
1148 i = findContainer( static_cast<const QWidget*>( o ) );
1149 if ( i != -1 )
1150 removeContainer( i );
1151 } while ( i != -1 );
1152
1153}
1154
1155int KAction::findContainer( const QWidget* widget ) const
1156{
1157 int pos = 0;
1158 QValueList<KActionPrivate::Container>::ConstIterator it = d->m_containers.begin();
1159 while( it != d->m_containers.end() )
1160 {
1161 if ( (*it).m_representative == widget || (*it).m_container == widget )
1162 return pos;
1163 ++it;
1164 ++pos;
1165 }
1166
1167 return -1;
1168}
1169
1170void KAction::removeContainer( int index )
1171{
1172 int i = 0;
1173 QValueList<KActionPrivate::Container>::Iterator it = d->m_containers.begin();
1174 while( it != d->m_containers.end() )
1175 {
1176 if ( i == index )
1177 {
1178 d->m_containers.remove( it );
1179 return;
1180 }
1181 ++it;
1182 ++i;
1183 }
1184}
1185
1186// FIXME: Remove this (ellis)
1187void KAction::slotKeycodeChanged()
1188{
1189 qDebug("KAction::slotKeycodeChanged() ...44 has top be fixed");
1190/*US
1191 kdDebug(129) << "KAction::slotKeycodeChanged()" << endl; // -- ellis
1192 KAccelAction* pAction = d->m_kaccel->actions().actionPtr(name());
1193 if( pAction )
1194 setShortcut(pAction->shortcut());
1195*/
1196}
1197
1198KActionCollection *KAction::parentCollection() const
1199{
1200 return m_parentCollection;
1201}
1202
1203void KAction::unplugAll()
1204{
1205 while ( containerCount() != 0 )
1206 unplug( container( 0 ) );
1207}
1208
1209void KAction::virtual_hook( int, void* )
1210{ /*BASE::virtual_hook( id, data );*/ }
1211
1212/* vim: et sw=2 ts=2
1213 */
1214
1215//US #include "kaction.moc"
diff --git a/microkde/kdeui/kaction.h b/microkde/kdeui/kaction.h
new file mode 100644
index 0000000..13e2e1e
--- a/dev/null
+++ b/microkde/kdeui/kaction.h
@@ -0,0 +1,624 @@
1/* This file is part of the KDE libraries
2 Copyright (C) 1999 Reginald Stadlbauer <reggie@kde.org>
3 (C) 1999 Simon Hausmann <hausmann@kde.org>
4 (C) 2000 Nicolas Hadacek <haadcek@kde.org>
5 (C) 2000 Kurt Granroth <granroth@kde.org>
6 (C) 2000 Michael Koch <koch@kde.org>
7 (C) 2001 Holger Freyther <freyther@kde.org>
8 (C) 2002 Ellis Whitehead <ellis@kde.org>
9
10 This library is free software; you can redistribute it and/or
11 modify it under the terms of the GNU Library General Public
12 License version 2 as published by the Free Software Foundation.
13
14 This library is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Library General Public License for more details.
18
19 You should have received a copy of the GNU Library General Public License
20 along with this library; see the file COPYING.LIB. If not, write to
21 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22 Boston, MA 02111-1307, USA.
23*/
24//$Id$
25
26#ifndef __kaction_h__
27#define __kaction_h__
28
29
30//US #include <qkeysequence.h>
31#include <qobject.h>
32#include <qvaluelist.h>
33#include <qguardedptr.h>
34#include <kguiitem.h>
35#include <kshortcut.h>
36#include <kstdaction.h>
37//US#include <kicontheme.h>
38
39//US added the following files
40#include <kiconloader.h>
41
42class QMenuBar;
43class QPopupMenu;
44//USclass QComboBox;
45//USclass QPoint;
46class QIconSet;
47class QString;
48class KToolBar;
49
50class KAccel;
51//USclass KAccelActions;
52//USclass KConfig;
53//USclass KConfigBase;
54//USclass KURL;
55//USclass KInstance;
56//USclass KToolBar;
57class KActionCollection;
58//USclass KPopupMenu;
59class KMainWindow;
60
61/**
62 * The KAction class (and derived and super classes) provides a way to
63 * easily encapsulate a "real" user-selected action or event in your
64 * program.
65 *
66 * For instance, a user may want to @p paste the contents of
67 * the clipboard or @p scroll @p down a document or @p quit the
68 * application. These are all @p actions -- events that the
69 * user causes to happen. The KAction class allows the developer to
70 * deal with these actions in an easy and intuitive manner.
71 *
72 * Specifically, the KAction class encapsulated the various attributes
73 * to an event/action. For instance, an action might have an icon
74 * that goes along with it (a clipboard for a "paste" action or
75 * scissors for a "cut" action). The action might have some text to
76 * describe the action. It will certainly have a method or function
77 * that actually @p executes the action! All these attributes
78 * are contained within the KAction object.
79 *
80 * The advantage of dealing with Actions is that you can manipulate
81 * the Action without regard to the GUI representation of it. For
82 * instance, in the "normal" way of dealing with actions like "cut",
83 * you would manually insert a item for Cut into a menu and a button
84 * into a toolbar. If you want to disable the cut action for a moment
85 * (maybe nothing is selected), you woud have to hunt down the pointer
86 * to the menu item and the toolbar button and disable both
87 * individually. Setting the menu item and toolbar item up uses very
88 * similar code - but has to be done twice!
89 *
90 * With the Action concept, you simply "plug" the Action into whatever
91 * GUI element you want. The KAction class will then take care of
92 * correctly defining the menu item (with icons, accelerators, text,
93 * etc) or toolbar button.. or whatever. From then on, if you
94 * manipulate the Action at all, the effect will propogate through all
95 * GUI representations of it. Back to the "cut" example: if you want
96 * to disable the Cut Action, you would simply do
97 * 'cutAction->setEnabled(false)' and the menuitem and button would
98 * instantly be disabled!
99 *
100 * This is the biggest advantage to the Action concept -- there is a
101 * one-to-one relationship between the "real" action and @p all
102 * GUI representations of it.
103 *
104 * KAction emits the activated() signal if the user activated the
105 * corresponding GUI element ( menu item, toolbar button, etc. )
106 *
107 * If you are in the situation of wanting to map the activated()
108 * signal of multiple action objects to one slot, with a special
109 * argument bound to each action, then you might consider using
110 * @ref QSignalMapper . A tiny example:
111 *
112 * <PRE>
113 * QSignalMapper *desktopNumberMapper = new QSignalMapper( this );
114 * connect( desktopNumberMapper, SIGNAL( mapped( int ) ),
115 * this, SLOT( moveWindowToDesktop( int ) ) );
116 *
117 * for ( uint i = 0; i < numberOfDesktops; ++i ) {
118 * KAction *desktopAction = new KAction( i18n( "Move Window to Desktop %i" ).arg( i ), ... );
119 * connect( desktopAction, SIGNAL( activated() ), desktopNumberMapper, SLOT( map() ) );
120 * desktopNumberMapper->setMapping( desktopAction, i );
121 * }
122 * </PRE>
123 *
124 * @sect General Usage:
125 *
126 * The steps to using actions are roughly as follows
127 *
128 * @li Decide which attributes you want to associate with a given
129 * action (icons, text, keyboard shortcut, etc)
130 * @li Create the action using KAction (or derived or super class).
131 * @li "Plug" the Action into whatever GUI element you want. Typically,
132 * this will be a menu or toolbar.
133 *
134 * @sect Detailed Example:
135 *
136 * Here is an example of enabling a "New [document]" action
137 * <PRE>
138 * KAction *newAct = new KAction(i18n("&New"), "filenew",
139 * KStdAccel::shortcut(KStdAccel::New),
140 * this, SLOT(fileNew()),
141 * actionCollection(), "new");
142 * </PRE>
143 * This line creates our action. It says that wherever this action is
144 * displayed, it will use "&New" as the text, the standard icon, and
145 * the standard shortcut. It further says that whenever this action
146 * is invoked, it will use the fileNew() slot to execute it.
147 *
148 * <PRE>
149 * QPopupMenu *file = new QPopupMenu;
150 * newAct->plug(file);
151 * </PRE>
152 * That just inserted the action into the File menu. The point is, it's not
153 * important in which menu it is: all manipulation of the item is
154 * done through the newAct object.
155 *
156 * <PRE>
157 * newAct->plug(toolBar());
158 * </PRE>
159 * And this inserted the Action into the main toolbar as a button.
160 *
161 * That's it!
162 *
163 * If you want to disable that action sometime later, you can do so
164 * with
165 * <PRE>
166 * newAct->setEnabled(false)
167 * </PRE>
168 * and both the menuitem in File and the toolbar button will instantly
169 * be disabled.
170 *
171 * Do not delete a KAction object without unplugging it from all its
172 * containers. The simplest way to do that is to use the unplugAll()
173 * as in the following example:
174 * <PRE>
175 * newAct->unplugAll();
176 * delete newAct;
177 * </PRE>
178 * Normally you will not need to do this as KActionCollection manages
179 * everything for you.
180 *
181 * Note: if you are using a "standard" action like "new", "paste",
182 * "quit", or any other action described in the KDE UI Standards,
183 * please use the methods in the @ref KStdAction class rather than
184 * defining your own.
185 *
186 * @sect Usage Within the XML Framework:
187 *
188 * If you are using KAction within the context of the XML menu and
189 * toolbar building framework, then there are a few tiny changes. The
190 * first is that you must insert your new action into an action
191 * collection. The action collection (a @ref KActionCollection) is,
192 * logically enough, a central collection of all of the actions
193 * defined in your application. The XML UI framework code in KXMLGUI
194 * classes needs access to this collection in order to build up the
195 * GUI (it's how the builder code knows which actions are valid and
196 * which aren't).
197 *
198 * Also, if you use the XML builder framework, then you do not ever
199 * have to plug your actions into containers manually. The framework
200 * does that for you.
201 *
202 * @see KStdAction
203 * @short Class to encapsulate user-driven action or event
204 */
205class KAction : public QObject
206{
207 friend class KActionCollection;
208 Q_OBJECT
209 Q_PROPERTY( int containerCount READ containerCount )
210 Q_PROPERTY( QString plainText READ plainText )
211 Q_PROPERTY( QString text READ text WRITE setText )
212 Q_PROPERTY( QString shortcut READ shortcutText WRITE setShortcutText )
213 Q_PROPERTY( bool enabled READ isEnabled WRITE setEnabled )
214 Q_PROPERTY( QString group READ group WRITE setGroup )
215 Q_PROPERTY( QString whatsThis READ whatsThis WRITE setWhatsThis )
216 Q_PROPERTY( QString toolTip READ toolTip WRITE setToolTip )
217 Q_PROPERTY( QString icon READ icon WRITE setIcon )
218public:
219 /**
220 * Constructs an action with text, potential keyboard
221 * shortcut, and a SLOT to call when this action is invoked by
222 * the user.
223 *
224 * If you do not want or have a keyboard shortcut,
225 * set the @p cut param to 0.
226 *
227 * This is the most common KAction used when you do not have a
228 * corresponding icon (note that it won't appear in the current version
229 * of the "Edit ToolBar" dialog, because an action needs an icon to be
230 * plugged in a toolbar...).
231 *
232 * @param text The text that will be displayed.
233 * @param cut The corresponding keyboard shortcut.
234 * @param receiver The SLOT's parent.
235 * @param slot The SLOT to invoke to execute this action.
236 * @param parent This action's parent.
237 * @param name An internal name for this action.
238 */
239 KAction( const QString& text, const KShortcut& cut,
240 const QObject* receiver, const char* slot,
241 KActionCollection* parent, const char* name );
242 /**
243 * Constructs an action with text, icon, potential keyboard
244 * shortcut, and a SLOT to call when this action is invoked by
245 * the user.
246 *
247 * If you do not want or have a keyboard shortcut, set the
248 * @p cut param to 0.
249 *
250 * This is the other common KAction used. Use it when you
251 * @p do have a corresponding icon.
252 *
253 * @param text The text that will be displayed.
254 * @param pix The icon to display.
255 * @param cut The corresponding keyboard shortcut.
256 * @param receiver The SLOT's parent.
257 * @param slot The SLOT to invoke to execute this action.
258 * @param parent This action's parent.
259 * @param name An internal name for this action.
260 */
261
262 KAction( const QString& text, const QIconSet& pix, const KShortcut& cut,
263 const QObject* receiver, const char* slot,
264 KActionCollection* parent, const char* name );
265
266 /**
267 * Constructs an action with text, icon, potential keyboard
268 * shortcut, and a SLOT to call when this action is invoked by
269 * the user. The icon is loaded on demand later based on where it
270 * is plugged in.
271 *
272 * If you do not want or have a keyboard shortcut, set the
273 * @p cut param to 0.
274 *
275 * This is the other common KAction used. Use it when you
276 * @p do have a corresponding icon.
277 *
278 * @param text The text that will be displayed.
279 * @param pix The icon to display.
280 * @param cut The corresponding keyboard shortcut (shortcut).
281 * @param receiver The SLOT's parent.
282 * @param slot The SLOT to invoke to execute this action.
283 * @param parent This action's parent.
284 * @param name An internal name for this action.
285 */
286 KAction( const QString& text, const QString& pix, const KShortcut& cut,
287 const QObject* receiver, const char* slot,
288 KActionCollection* parent, const char* name );
289
290 /**
291 * The same as the above constructor, but with a KGuiItem providing
292 * the text and icon.
293 *
294 * @param item The KGuiItem with the label and (optional) icon.
295 */
296 KAction( const KGuiItem& item, const KShortcut& cut,
297 const QObject* receiver, const char* slot,
298 KActionCollection* parent, const char* name );
299 /**
300 * @obsolete
301 */
302 KAction( const QString& text, const KShortcut& cut = KShortcut(), QObject* parent = 0, const char* name = 0 );
303 /**
304 * @obsolete
305 */
306 KAction( const QString& text, const KShortcut& cut,
307 const QObject* receiver, const char* slot, QObject* parent, const char* name = 0 );
308 /**
309 * @obsolete
310 */
311 KAction( const QString& text, const QIconSet& pix, const KShortcut& cut = KShortcut(),
312 QObject* parent = 0, const char* name = 0 );
313 /**
314 * @obsolete
315 */
316 KAction( const QString& text, const QString& pix, const KShortcut& cut = KShortcut(),
317 QObject* parent = 0, const char* name = 0 );
318 /**
319 * @obsolete
320 */
321 KAction( const QString& text, const QIconSet& pix, const KShortcut& cut,
322 const QObject* receiver, const char* slot, QObject* parent, const char* name = 0 );
323 /**
324 * @obsolete
325 */
326 KAction( const QString& text, const QString& pix, const KShortcut& cut,
327 const QObject* receiver, const char* slot, QObject* parent,
328 const char* name = 0 );
329 /**
330 * @obsolete
331 */
332 KAction( QObject* parent = 0, const char* name = 0 );
333
334 /**
335 * Standard destructor
336 */
337 virtual ~KAction();
338
339 /**
340 * "Plug" or insert this action into a given widget.
341 *
342 * This will
343 * typically be a menu or a toolbar. From this point on, you will
344 * never need to directly manipulate the item in the menu or
345 * toolbar. You do all enabling/disabling/manipulation directly
346 * with your KAction object.
347 *
348 * @param w The GUI element to display this action
349 */
350 virtual int plug( QWidget *w, int index = -1 );
351
352 /**
353 * @deprecated. Shouldn't be used. No substitute available.
354 *
355 * "Plug" or insert this action into a given KAccel.
356 *
357 * @param accel The KAccel collection which holds this accel
358 * @param configurable If the shortcut is configurable via
359 * the KAccel configuration dialog (this is somehow deprecated since
360 * there is now a KAction key configuration dialog).
361 */
362 virtual void plugAccel(KAccel *accel, bool configurable = true);
363
364 /**
365 * "Unplug" or remove this action from a given widget.
366 *
367 * This will typically be a menu or a toolbar. This is rarely
368 * used in "normal" application. Typically, it would be used if
369 * your application has several views or modes, each with a
370 * completely different menu structure. If you simply want to
371 * disable an action for a given period, use @ref setEnabled()
372 * instead.
373 *
374 * @param w Remove the action from this GUI element.
375 */
376 virtual void unplug( QWidget *w );
377
378 /**
379 * @deprecated. Complement method to plugAccel().
380 * Disconnect this action from the KAccel.
381 */
382 virtual void unplugAccel();
383
384 /**
385 * returns whether the action is plugged into any container widget or not.
386 * @since 3.1
387 */
388 virtual bool isPlugged() const;
389
390 /**
391 * returns whether the action is plugged into the given container
392 */
393 bool isPlugged( const QWidget *container ) const;
394
395 /**
396 * returns whether the action is plugged into the given container with the given, container specific, id (often
397 * menu or toolbar id ) .
398 */
399 virtual bool isPlugged( const QWidget *container, int id ) const;
400
401 /**
402 * returns whether the action is plugged into the given container with the given, container specific, representative
403 * container widget item.
404 */
405 virtual bool isPlugged( const QWidget *container, const QWidget *_representative ) const;
406
407 QWidget* container( int index ) const;
408 int itemId( int index ) const;
409 QWidget* representative( int index ) const;
410 int containerCount() const;
411 /// @since 3.1
412 uint kaccelCount() const;
413
414 virtual bool hasIcon() const;
415#ifndef KDE_NO_COMPAT
416 bool hasIconSet() const { return hasIcon(); }
417#endif
418 virtual QString plainText() const;
419
420 /**
421 * Get the text associated with this action.
422 */
423 virtual QString text() const;
424
425 /**
426 * Get the keyboard shortcut associated with this action.
427 */
428 virtual const KShortcut& shortcut() const;
429 /**
430 * Get the default shortcut for this action.
431 */
432 virtual const KShortcut& shortcutDefault() const;
433
434 // These two methods are for Q_PROPERTY
435 QString shortcutText() const;
436 void setShortcutText( const QString& );
437
438 /**
439 * Returns true if this action is enabled.
440 */
441 virtual bool isEnabled() const;
442
443 /**
444 * Returns true if this action's shortcut is configurable.
445 */
446 virtual bool isShortcutConfigurable() const;
447
448 virtual QString group() const;
449
450 /**
451 * Get the What's this text for the action.
452 */
453 virtual QString whatsThis() const;
454
455 /**
456 * Get the tooltip text for the action.
457 */
458 virtual QString toolTip() const;
459
460 /**
461 * Get the QIconSet from which the icons used to display this action will
462 * be chosen.
463 */
464 virtual QIconSet iconSet( KIcon::Group group, int size=0 ) const;
465
466#ifndef KDE_NO_COMPAT
467 QIconSet iconSet() const
468 {
469 return iconSet( KIcon::Small );
470 }
471#endif
472
473 virtual QString icon() const;
474
475 KActionCollection *parentCollection() const;
476
477 /**
478 * @internal
479 * Generate a toolbar button id. Made public for reimplementations.
480 */
481 static int getToolButtonID();
482
483
484 void unplugAll();
485
486public slots:
487 /**
488 * Sets the text associated with this action. The text is used for menu
489 * and toolbar labels etc.
490 */
491 virtual void setText(const QString &text);
492
493 /**
494 * Sets the keyboard shortcut associated with this action.
495 */
496 virtual bool setShortcut( const KShortcut& );
497
498 virtual void setGroup( const QString& );
499
500 /**
501 * Sets the What's this text for the action. This text will be displayed when
502 * a widget that has been created by plugging this action into a container
503 * is clicked on in What's this mode.
504 *
505 * The What's this text can include QML markup as well as raw text.
506 */
507 virtual void setWhatsThis( const QString& text );
508
509 /**
510 * Sets the tooltip text for the action.
511 * This will be used as a tooltip for a toolbar button, as a
512 * statusbar help-text for a menu item, and it also appears
513 * in the toolbar editor, to describe the action.
514 */
515 virtual void setToolTip( const QString& );
516
517 /**
518 * Sets the QIconSet from which the icons used to display this action will
519 * be chosen.
520 */
521 virtual void setIconSet( const QIconSet &iconSet );
522
523 virtual void setIcon( const QString& icon );
524
525 /**
526 * Enables or disables this action. All uses of this action (eg. in menus
527 * or toolbars) will be updated to reflect the state of the action.
528 */
529 virtual void setEnabled(bool enable);
530
531 /**
532 * Indicate whether the user may configure the action's shortcut.
533 */
534 virtual void setShortcutConfigurable( bool );
535
536 /**
537 * Emulate user's interaction programmatically, by activating the action.
538 * The implementation simply emits activated().
539 */
540 virtual void activate();
541
542protected slots:
543 virtual void slotDestroyed();
544 virtual void slotKeycodeChanged();
545 virtual void slotActivated();
546
547protected:
548 KToolBar* toolBar( int index ) const;
549 QPopupMenu* popupMenu( int index ) const;
550 void removeContainer( int index );
551 int findContainer( const QWidget* widget ) const;
552 void plugMainWindowAccel( QWidget *w );
553
554 void addContainer( QWidget* parent, int id );
555 void addContainer( QWidget* parent, QWidget* representative );
556
557 virtual void updateShortcut( int i );
558 virtual void updateShortcut( QPopupMenu* menu, int id );
559 virtual void updateGroup( int id );
560 virtual void updateText(int i );
561 virtual void updateEnabled(int i);
562 virtual void updateIconSet(int i);
563 virtual void updateIcon( int i);
564 virtual void updateToolTip( int id );
565 virtual void updateWhatsThis( int i );
566
567 KActionCollection *m_parentCollection;
568 QString whatsThisWithIcon() const;
569
570signals:
571 void activated();
572 void enabled( bool );
573
574private:
575 void initPrivate( const QString& text, const KShortcut& cut,
576 const QObject* receiver, const char* slot );
577 KAccel* kaccelCurrent();
578 bool initShortcut( const KShortcut& );
579 void plugShortcut();
580 bool updateKAccelShortcut( KAccel* kaccel );
581 void insertKAccel( KAccel* );
582 /** @internal To be used exclusively by KActionCollection::removeWidget(). */
583 void removeKAccel( KAccel* );
584
585#ifndef KDE_NO_COMPAT
586public:
587 /**
588 * @deprecated. Use shortcut().
589 * Get the keyboard accelerator associated with this action.
590 */
591 int accel() const;
592
593 QString statusText() const
594 { return toolTip(); }
595
596 /**
597 * @deprecated. Use setShortcut().
598 * Sets the keyboard accelerator associated with this action.
599 */
600 void setAccel( int key );
601
602 /**
603 * @deprecated. Use setToolTip instead (they do the same thing now).
604 */
605 void setStatusText( const QString &text )
606 { setToolTip( text ); }
607
608 /**
609 * @deprecated. for backwards compatibility.
610 */
611 int menuId( int i ) { return itemId( i ); }
612#endif // !KDE_NO_COMPAT
613
614protected:
615 virtual void virtual_hook( int id, void* data );
616private:
617 class KActionPrivate;
618 KActionPrivate *d;
619};
620
621#include <kactioncollection.h>
622#include <kactionclasses.h>
623
624#endif
diff --git a/microkde/kdeui/kactionclasses.cpp b/microkde/kdeui/kactionclasses.cpp
new file mode 100644
index 0000000..82e6c8b
--- a/dev/null
+++ b/microkde/kdeui/kactionclasses.cpp
@@ -0,0 +1,2058 @@
1/* This file is part of the KDE libraries
2 Copyright (C) 1999 Reginald Stadlbauer <reggie@kde.org>
3 (C) 1999 Simon Hausmann <hausmann@kde.org>
4 (C) 2000 Nicolas Hadacek <haadcek@kde.org>
5 (C) 2000 Kurt Granroth <granroth@kde.org>
6 (C) 2000 Michael Koch <koch@kde.org>
7 (C) 2001 Holger Freyther <freyther@kde.org>
8 (C) 2002 Ellis Whitehead <ellis@kde.org>
9 (C) 2002 Joseph Wenninger <jowenn@kde.org>
10
11 This library is free software; you can redistribute it and/or
12 modify it under the terms of the GNU Library General Public
13 License version 2 as published by the Free Software Foundation.
14
15 This library is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 Library General Public License for more details.
19
20 You should have received a copy of the GNU Library General Public License
21 along with this library; see the file COPYING.LIB. If not, write to
22 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23 Boston, MA 02111-1307, USA.
24*/
25
26#include "kactionclasses.h"
27
28#include <assert.h>
29
30#include <qfontdatabase.h>
31#include <qobjectlist.h>
32//US#include <qwhatsthis.h>
33#include <qtimer.h>
34
35//US#include <kaccel.h>
36//US#include <kapplication.h>
37#include <kconfig.h>
38#include <kdebug.h>
39//US#include <kfontcombo.h>
40//US#include <kmainwindow.h>
41//US#include <kmenubar.h>
42//US#include <kpopupmenu.h>
43#include <kcombobox.h>
44#include <ktoolbar.h>
45#include <ktoolbarbutton.h>
46#include <kurl.h>
47
48//US added the following includefiles
49#include <kconfigbase.h>
50#include <qwidget.h>
51#include <qpopupmenu.h>
52#include <qmenubar.h>
53#include <qmainwindow.h>
54#include <qtoolbar.h>
55#include <qcombobox.h>
56#include <qmainwindow.h>
57
58
59static QFontDatabase *fontDataBase = 0;
60
61static void cleanupFontDatabase()
62{
63 delete fontDataBase;
64 fontDataBase = 0;
65}
66
67static void get_fonts( QStringList &lst )
68{
69 if ( !fontDataBase ) {
70 fontDataBase = new QFontDatabase();
71 qAddPostRoutine( cleanupFontDatabase );
72 }
73 lst.clear();
74 QStringList families = fontDataBase->families();
75 for ( QStringList::Iterator it = families.begin(); it != families.end(); ++it )
76 {
77 QString family = *it;
78 if ( family. contains('-') ) // remove foundry
79 family = family.right( family.length() - family.find('-' ) - 1);
80 if ( !lst.contains( family ) )
81 lst.append( family );
82 }
83 lst.sort();
84}
85
86static QValueList<int> get_standard_font_sizes()
87{
88 if ( !fontDataBase ) {
89 fontDataBase = new QFontDatabase();
90 qAddPostRoutine( cleanupFontDatabase );
91 }
92 return fontDataBase->standardSizes();
93}
94
95class KToggleAction::KToggleActionPrivate
96{
97public:
98 KToggleActionPrivate()
99 {
100 m_checked = false;
101 }
102
103 bool m_checked;
104 QString m_exclusiveGroup;
105};
106
107KToggleAction::KToggleAction( const QString& text, const KShortcut& cut,
108 QObject* parent,
109 const char* name )
110 : KAction( text, cut, parent, name )
111{
112 d = new KToggleActionPrivate;
113}
114
115KToggleAction::KToggleAction( const QString& text, const KShortcut& cut,
116 const QObject* receiver, const char* slot,
117 QObject* parent, const char* name )
118 : KAction( text, cut, receiver, slot, parent, name )
119{
120 d = new KToggleActionPrivate;
121}
122
123KToggleAction::KToggleAction( const QString& text, const QIconSet& pix,
124 const KShortcut& cut,
125 QObject* parent, const char* name )
126 : KAction( text, pix, cut, parent, name )
127{
128 d = new KToggleActionPrivate;
129}
130
131KToggleAction::KToggleAction( const QString& text, const QString& pix,
132 const KShortcut& cut,
133 QObject* parent, const char* name )
134 : KAction( text, pix, cut, parent, name )
135{
136 d = new KToggleActionPrivate;
137}
138
139KToggleAction::KToggleAction( const QString& text, const QIconSet& pix,
140 const KShortcut& cut,
141 const QObject* receiver,
142 const char* slot, QObject* parent,
143 const char* name )
144 : KAction( text, pix, cut, receiver, slot, parent, name )
145{
146 d = new KToggleActionPrivate;
147}
148
149KToggleAction::KToggleAction( const QString& text, const QString& pix,
150 const KShortcut& cut,
151 const QObject* receiver,
152 const char* slot, QObject* parent,
153 const char* name )
154 : KAction( text, pix, cut, receiver, slot, parent, name )
155{
156 d = new KToggleActionPrivate;
157}
158
159KToggleAction::KToggleAction( QObject* parent, const char* name )
160 : KAction( parent, name )
161{
162 d = new KToggleActionPrivate;
163}
164
165KToggleAction::~KToggleAction()
166{
167 delete d;
168}
169
170int KToggleAction::plug( QWidget* widget, int index )
171{
172 if ( !widget->inherits("QPopupMenu") && !widget->inherits("KToolBar") )
173 {
174 kdWarning() << "Can not plug KToggleAction in " << widget->className() << endl;
175 return -1;
176 }
177
178/*US
179 if (kapp && !kapp->authorizeKAction(name()))
180 return -1;
181*/
182
183 int _index = KAction::plug( widget, index );
184 if ( _index == -1 )
185 return _index;
186
187 if ( widget->inherits("QPopupMenu") )
188 {
189 int id = itemId( _index );
190
191 static_cast<QPopupMenu*>(widget)->setItemChecked( id, d->m_checked );
192 } else if ( widget->inherits( "KToolBar" ) ) {
193
194 KToolBar *bar = static_cast<KToolBar *>( widget );
195
196 bar->setToggle( itemId( _index ), true );
197 bar->setButton( itemId( _index ), isChecked() );
198 }
199
200 return _index;
201}
202
203void KToggleAction::setChecked( bool c )
204{
205 if ( c == d->m_checked )
206 return;
207 //kdDebug(129) << "KToggleAction::setChecked(" << c << ") " << this << " " << name() << endl;
208
209 d->m_checked = c;
210
211 int len = containerCount();
212
213 for( int i = 0; i < len; ++i )
214 updateChecked( i );
215
216 if ( c && parent() && !exclusiveGroup().isEmpty() ) {
217 const QObjectList *list = parent()->children();
218 if ( list ) {
219 QObjectListIt it( *list );
220 for( ; it.current(); ++it ) {
221 if ( it.current()->inherits( "KToggleAction" ) && it.current() != this &&
222 static_cast<KToggleAction*>(it.current())->exclusiveGroup() == exclusiveGroup() ) {
223 KToggleAction *a = static_cast<KToggleAction*>(it.current());
224 if( a->isChecked() ) {
225 a->setChecked( false );
226 emit a->toggled( false );
227 }
228 }
229 }
230 }
231 }
232}
233
234void KToggleAction::updateChecked( int id )
235{
236 QWidget *w = container( id );
237
238 if ( w->inherits( "QPopupMenu" ) )
239 static_cast<QPopupMenu*>(w)->setItemChecked( itemId( id ), d->m_checked );
240 else if ( w->inherits( "QMenuBar" ) )
241 static_cast<QMenuBar*>(w)->setItemChecked( itemId( id ), d->m_checked );
242 else if ( w->inherits( "KToolBar" ) )
243 {
244 QWidget* r = static_cast<KToolBar*>( w )->getButton( itemId( id ) );
245 if ( r && r->inherits( "KToolBarButton" ) )
246 static_cast<KToolBar*>( w )->setButton( itemId( id ), d->m_checked );
247 }
248}
249
250void KToggleAction::slotActivated()
251{
252 setChecked( !isChecked() );
253 emit activated();
254 emit toggled( isChecked() );
255}
256
257bool KToggleAction::isChecked() const
258{
259 return d->m_checked;
260}
261
262void KToggleAction::setExclusiveGroup( const QString& name )
263{
264 d->m_exclusiveGroup = name;
265}
266
267QString KToggleAction::exclusiveGroup() const
268{
269 return d->m_exclusiveGroup;
270}
271
272
273KRadioAction::KRadioAction( const QString& text, const KShortcut& cut,
274 QObject* parent, const char* name )
275: KToggleAction( text, cut, parent, name )
276{
277}
278
279KRadioAction::KRadioAction( const QString& text, const KShortcut& cut,
280 const QObject* receiver, const char* slot,
281 QObject* parent, const char* name )
282: KToggleAction( text, cut, receiver, slot, parent, name )
283{
284}
285
286KRadioAction::KRadioAction( const QString& text, const QIconSet& pix,
287 const KShortcut& cut,
288 QObject* parent, const char* name )
289: KToggleAction( text, pix, cut, parent, name )
290{
291}
292
293KRadioAction::KRadioAction( const QString& text, const QString& pix,
294 const KShortcut& cut,
295 QObject* parent, const char* name )
296: KToggleAction( text, pix, cut, parent, name )
297{
298}
299
300KRadioAction::KRadioAction( const QString& text, const QIconSet& pix,
301 const KShortcut& cut,
302 const QObject* receiver, const char* slot,
303 QObject* parent, const char* name )
304: KToggleAction( text, pix, cut, receiver, slot, parent, name )
305{
306}
307
308KRadioAction::KRadioAction( const QString& text, const QString& pix,
309 const KShortcut& cut,
310 const QObject* receiver, const char* slot,
311 QObject* parent, const char* name )
312: KToggleAction( text, pix, cut, receiver, slot, parent, name )
313{
314}
315
316KRadioAction::KRadioAction( QObject* parent, const char* name )
317: KToggleAction( parent, name )
318{
319}
320
321void KRadioAction::slotActivated()
322{
323 if ( isChecked() )
324 {
325 const QObject *senderObj = sender();
326
327 if ( !senderObj || !senderObj->inherits( "KToolBarButton" ) )
328 return;
329
330 qDebug("KRadioAction::slotActivated has to be fixed");
331 const_cast<KToolBarButton *>( static_cast<const KToolBarButton *>( senderObj ) )->on( true );
332
333 return;
334 }
335
336 KToggleAction::slotActivated();
337}
338
339class KSelectAction::KSelectActionPrivate
340{
341public:
342 KSelectActionPrivate()
343 {
344 m_edit = false;
345 m_menuAccelsEnabled = true;
346 m_menu = 0;
347 m_current = -1;
348 m_comboWidth = -1;
349 }
350 bool m_edit;
351 bool m_menuAccelsEnabled;
352 QPopupMenu *m_menu;
353 int m_current;
354 int m_comboWidth;
355 QStringList m_list;
356
357 QString makeMenuText( const QString &_text )
358 {
359 if ( m_menuAccelsEnabled )
360 return _text;
361 QString text = _text;
362 uint i = 0;
363 while ( i < text.length() ) {
364 if ( text.at( i ) == '&' ) {
365 text.insert( i, '&' );
366 i += 2;
367 }
368 else
369 ++i;
370 }
371 return text;
372 }
373};
374
375KSelectAction::KSelectAction( const QString& text, const KShortcut& cut,
376 QObject* parent, const char* name )
377 : KAction( text, cut, parent, name )
378{
379 d = new KSelectActionPrivate;
380}
381
382KSelectAction::KSelectAction( const QString& text, const KShortcut& cut,
383 const QObject* receiver, const char* slot,
384 QObject* parent, const char* name )
385 : KAction( text, cut, receiver, slot, parent, name )
386{
387 d = new KSelectActionPrivate;
388}
389
390KSelectAction::KSelectAction( const QString& text, const QIconSet& pix,
391 const KShortcut& cut,
392 QObject* parent, const char* name )
393 : KAction( text, pix, cut, parent, name )
394{
395 d = new KSelectActionPrivate;
396}
397
398KSelectAction::KSelectAction( const QString& text, const QString& pix,
399 const KShortcut& cut,
400 QObject* parent, const char* name )
401 : KAction( text, pix, cut, parent, name )
402{
403 d = new KSelectActionPrivate;
404}
405
406KSelectAction::KSelectAction( const QString& text, const QIconSet& pix,
407 const KShortcut& cut,
408 const QObject* receiver,
409 const char* slot, QObject* parent,
410 const char* name )
411 : KAction( text, pix, cut, receiver, slot, parent, name )
412{
413 d = new KSelectActionPrivate;
414}
415
416KSelectAction::KSelectAction( const QString& text, const QString& pix,
417 const KShortcut& cut,
418 const QObject* receiver,
419 const char* slot, QObject* parent,
420 const char* name )
421 : KAction( text, pix, cut, receiver, slot, parent, name )
422{
423 d = new KSelectActionPrivate;
424}
425
426KSelectAction::KSelectAction( QObject* parent, const char* name )
427 : KAction( parent, name )
428{
429 d = new KSelectActionPrivate;
430}
431
432KSelectAction::~KSelectAction()
433{
434 assert(d);
435 delete d->m_menu;
436 delete d; d = 0;
437}
438
439void KSelectAction::setCurrentItem( int id )
440{
441 if ( id >= (int)d->m_list.count() ) {
442 ASSERT(id < (int)d->m_list.count());
443 return;
444 }
445
446 if ( d->m_menu )
447 {
448 if ( d->m_current >= 0 )
449 d->m_menu->setItemChecked( d->m_current, false );
450 if ( id >= 0 )
451 {
452 //US qDebug("KSelectAction::setCurrentItem %i", id);
453 d->m_menu->setItemChecked( id, true );
454 }
455 }
456
457 d->m_current = id;
458
459 int len = containerCount();
460
461 for( int i = 0; i < len; ++i )
462 updateCurrentItem( i );
463
464 // emit KAction::activated();
465 // emit activated( currentItem() );
466 // emit activated( currentText() );
467}
468
469void KSelectAction::setComboWidth( int width )
470{
471 if ( width < 0 )
472 return;
473
474 d->m_comboWidth=width;
475
476 int len = containerCount();
477
478 for( int i = 0; i < len; ++i )
479 updateComboWidth( i );
480
481}
482QPopupMenu* KSelectAction::popupMenu() const
483{
484 kdDebug(129) << "KSelectAction::popupMenu()" << endl; // remove -- ellis
485 if ( !d->m_menu )
486 {
487//US d->m_menu = new KPopupMenu(0L, "KSelectAction::popupMenu()");
488 d->m_menu = new QPopupMenu(0L, "QSelectAction::popupMenu()");
489 setupMenu();
490 if ( d->m_current >= 0 )
491 d->m_menu->setItemChecked( d->m_current, true );
492 }
493
494 return d->m_menu;
495}
496
497void KSelectAction::setupMenu() const
498{
499 if ( !d->m_menu )
500 return;
501 d->m_menu->clear();
502
503 QStringList::ConstIterator it = d->m_list.begin();
504 for( uint id = 0; it != d->m_list.end(); ++it, ++id ) {
505 QString text = *it;
506 if ( !text.isEmpty() )
507 d->m_menu->insertItem( d->makeMenuText( text ), this, SLOT( slotActivated( int ) ), 0, id );
508 else
509 d->m_menu->insertSeparator();
510 }
511}
512
513void KSelectAction::changeItem( int index, const QString& text )
514{
515 if ( index < 0 || index >= (int)d->m_list.count() )
516 {
517 kdWarning() << "KSelectAction::changeItem Index out of scope" << endl;
518 return;
519 }
520
521 d->m_list[ index ] = text;
522
523 if ( d->m_menu )
524 d->m_menu->changeItem( index, d->makeMenuText( text ) );
525
526 int len = containerCount();
527 for( int i = 0; i < len; ++i )
528 changeItem( i, index, text );
529}
530
531void KSelectAction::changeItem( int id, int index, const QString& text)
532{
533 if ( index < 0 )
534 return;
535
536 QWidget* w = container( id );
537 if ( w->inherits( "KToolBar" ) )
538 {
539 QWidget* r = (static_cast<KToolBar*>( w ))->getWidget( itemId( id ) );
540 if ( r->inherits( "QComboBox" ) )
541 {
542 QComboBox *b = static_cast<QComboBox*>( r );
543 b->changeItem(text, index );
544 }
545 }
546
547}
548
549void KSelectAction::setItems( const QStringList &lst )
550{
551 kdDebug(129) << "KAction::setItems()" << endl; // remove -- ellis
552 d->m_list = lst;
553 d->m_current = -1;
554
555 setupMenu();
556
557 int len = containerCount();
558 for( int i = 0; i < len; ++i )
559 updateItems( i );
560
561 // Disable if empty and not editable
562 setEnabled ( lst.count() > 0 || d->m_edit );
563}
564
565QStringList KSelectAction::items() const
566{
567 return d->m_list;
568}
569
570QString KSelectAction::currentText() const
571{
572 if ( currentItem() < 0 )
573 return QString::null;
574
575 return d->m_list[ currentItem() ];
576}
577
578int KSelectAction::currentItem() const
579{
580 return d->m_current;
581}
582
583void KSelectAction::updateCurrentItem( int id )
584{
585 if ( d->m_current < 0 )
586 return;
587
588 QWidget* w = container( id );
589 if ( w->inherits( "KToolBar" ) ) {
590 QWidget* r = static_cast<KToolBar*>( w )->getWidget( itemId( id ) );
591 if ( r->inherits( "QComboBox" ) ) {
592 QComboBox *b = static_cast<QComboBox*>( r );
593 b->setCurrentItem( d->m_current );
594 }
595 }
596}
597
598int KSelectAction::comboWidth() const
599{
600 return d->m_comboWidth;
601}
602
603void KSelectAction::updateComboWidth( int id )
604{
605 QWidget* w = container( id );
606 if ( w->inherits( "KToolBar" ) ) {
607 QWidget* r = static_cast<KToolBar*>( w )->getWidget( itemId( id ) );
608 if ( r->inherits( "QComboBox" ) ) {
609 QComboBox *cb = static_cast<QComboBox*>( r );
610 cb->setMinimumWidth( d->m_comboWidth );
611 cb->setMaximumWidth( d->m_comboWidth );
612 }
613 }
614}
615
616void KSelectAction::updateItems( int id )
617{
618 kdDebug(129) << "KAction::updateItems( " << id << ", lst )" << endl; // remove -- ellis
619
620 QWidget* w = container( id );
621 if ( w->inherits( "KToolBar" ) ) {
622
623 QWidget* r = static_cast<KToolBar*>( w )->getWidget( itemId( id ) );
624 if ( r->inherits( "QComboBox" ) ) {
625 QComboBox *cb = static_cast<QComboBox*>( r );
626 cb->clear();
627 QStringList lst = comboItems();
628 QStringList::ConstIterator it = lst.begin();
629 for( ; it != lst.end(); ++it )
630 cb->insertItem( *it );
631 // Ok, this currently doesn't work due to a bug in QComboBox
632 // (the sizehint is cached for ever and never recalculated)
633 // Bug reported (against Qt 2.3.1).
634 cb->setMinimumWidth( cb->sizeHint().width() );
635 }
636 }
637
638}
639
640int KSelectAction::plug( QWidget *widget, int index )
641{
642//US if (kapp && !kapp->authorizeKAction(name()))
643//US return -1;
644
645 kdDebug(129) << "KAction::plug( " << widget << ", " << index << " )" << endl; // remove -- ellis
646 if ( widget->inherits("QPopupMenu") )
647 {
648 // Create the PopupMenu and store it in m_menu
649 (void)popupMenu();
650
651 QPopupMenu* menu = static_cast<QPopupMenu*>( widget );
652 int id;
653
654 if ( hasIconSet() )
655 id = menu->insertItem( iconSet(), text(), d->m_menu, -1, index );
656 else
657 id = menu->insertItem( text(), d->m_menu, -1, index );
658
659 if ( !isEnabled() )
660 menu->setItemEnabled( id, false );
661
662 QString wth = whatsThis();
663 if ( !wth.isEmpty() )
664 menu->setWhatsThis( id, wth );
665
666 addContainer( menu, id );
667 connect( menu, SIGNAL( destroyed() ), this, SLOT( slotDestroyed() ) );
668
669 return containerCount() - 1;
670 }
671 else if ( widget->inherits("KToolBar") )
672 {
673
674 KToolBar* bar = static_cast<KToolBar*>( widget );
675 int id_ = KAction::getToolButtonID();
676 bar->insertCombo( comboItems(), id_, isEditable(),
677 SIGNAL( activated( const QString & ) ), this,
678 SLOT( slotActivated( const QString & ) ), isEnabled(),
679 toolTip(), -1, index );
680
681 KComboBox *cb = bar->getCombo( id_ );
682 if ( cb )
683 {
684 cb->setMaximumHeight( 34 );
685 if (!isEditable()) cb->setFocusPolicy(QWidget::NoFocus);
686 cb->setMinimumWidth( cb->sizeHint().width() );
687 if ( d->m_comboWidth > 0 )
688 {
689 cb->setMinimumWidth( d->m_comboWidth );
690 cb->setMaximumWidth( d->m_comboWidth );
691 }
692 cb->setInsertionPolicy( QComboBox::NoInsertion );
693//US QWhatsThis::add( cb, whatsThis() );
694 }
695
696 addContainer( bar, id_ );
697
698 connect( bar, SIGNAL( destroyed() ), this, SLOT( slotDestroyed() ) );
699
700 updateCurrentItem( containerCount() - 1 );
701
702 return containerCount() - 1;
703
704 }
705 kdWarning() << "Can not plug KAction in " << widget->className() << endl;
706 return -1;
707}
708
709QStringList KSelectAction::comboItems() const
710{
711 //qDebug("KSelectAction::comboItems has to be fixed");
712 if( d->m_menuAccelsEnabled )
713 {
714 QStringList lst;
715 QStringList::ConstIterator it = d->m_list.begin();
716 for( ; it != d->m_list.end(); ++it )
717 {
718 QString item = *it;
719 int i = item.find( '&' );
720 if ( i > -1 )
721 item = item.remove( i, 1 );
722 lst.append( item );
723 }
724 return lst;
725 }
726 else
727 {
728 return d->m_list;
729 }
730}
731
732void KSelectAction::clear()
733{
734 if ( d->m_menu )
735 d->m_menu->clear();
736
737 int len = containerCount();
738 for( int i = 0; i < len; ++i )
739 updateClear( i );
740}
741
742void KSelectAction::updateClear( int id )
743{
744
745 QWidget* w = container( id );
746 if ( w->inherits( "KToolBar" ) ) {
747 QWidget* r = static_cast<KToolBar*>( w )->getWidget( itemId( id ) );
748 if ( r->inherits( "QComboBox" ) ) {
749 QComboBox *b = static_cast<QComboBox*>( r );
750 b->clear();
751 }
752 }
753}
754
755void KSelectAction::slotActivated( int id )
756{
757 if ( d->m_current == id )
758 return;
759
760 setCurrentItem( id );
761 // Delay this. Especially useful when the slot connected to activated() will re-create
762 // the menu, e.g. in the recent files action. This prevents a crash.
763
764 QTimer::singleShot( 0, this, SLOT( slotActivated() ) );
765}
766
767void KSelectAction::slotActivated( const QString &text )
768{
769 if ( isEditable() )
770 {
771 QStringList lst = items();
772 if(lst.contains(text)==0)
773 {
774 lst.append( text );
775 setItems( lst );
776 }
777 }
778
779 int i = items().findIndex( text );
780 if ( i > -1 )
781 setCurrentItem( i );
782 else
783 setCurrentItem( comboItems().findIndex( text ) );
784 // Delay this. Especially useful when the slot connected to activated() will re-create
785 // the menu, e.g. in the recent files action. This prevents a crash.
786
787 QTimer::singleShot( 0, this, SLOT( slotActivated() ) );
788}
789
790void KSelectAction::slotActivated()
791{
792 KAction::slotActivated();
793 kdDebug(129) << "KSelectAction::slotActivated currentItem=" << currentItem() << " currentText=" << currentText() << endl;
794 emit activated( currentItem() );
795 emit activated( currentText() );
796}
797
798void KSelectAction::setEditable( bool edit )
799{
800 d->m_edit = edit;
801}
802
803bool KSelectAction::isEditable() const
804{
805 return d->m_edit;
806}
807
808void KSelectAction::setRemoveAmpersandsInCombo( bool b )
809{
810 setMenuAccelsEnabled( b );
811}
812
813bool KSelectAction::removeAmpersandsInCombo() const
814{
815 return menuAccelsEnabled( );
816}
817
818void KSelectAction::setMenuAccelsEnabled( bool b )
819{
820 d->m_menuAccelsEnabled = b;
821}
822
823bool KSelectAction::menuAccelsEnabled() const
824{
825 return d->m_menuAccelsEnabled;
826}
827
828class KListAction::KListActionPrivate
829{
830public:
831 KListActionPrivate()
832 {
833 m_current = 0;
834 }
835 int m_current;
836};
837
838KListAction::KListAction( const QString& text, const KShortcut& cut,
839 QObject* parent, const char* name )
840 : KSelectAction( text, cut, parent, name )
841{
842 d = new KListActionPrivate;
843}
844
845KListAction::KListAction( const QString& text, const KShortcut& cut,
846 const QObject* receiver, const char* slot,
847 QObject* parent, const char* name )
848 : KSelectAction( text, cut, parent, name )
849{
850 d = new KListActionPrivate;
851 if ( receiver )
852 connect( this, SIGNAL( activated( int ) ), receiver, slot );
853}
854
855KListAction::KListAction( const QString& text, const QIconSet& pix,
856 const KShortcut& cut,
857 QObject* parent, const char* name )
858 : KSelectAction( text, pix, cut, parent, name )
859{
860 d = new KListActionPrivate;
861}
862
863KListAction::KListAction( const QString& text, const QString& pix,
864 const KShortcut& cut,
865 QObject* parent, const char* name )
866 : KSelectAction( text, pix, cut, parent, name )
867{
868 d = new KListActionPrivate;
869}
870
871KListAction::KListAction( const QString& text, const QIconSet& pix,
872 const KShortcut& cut, const QObject* receiver,
873 const char* slot, QObject* parent,
874 const char* name )
875 : KSelectAction( text, pix, cut, parent, name )
876{
877 d = new KListActionPrivate;
878 if ( receiver )
879 connect( this, SIGNAL( activated( int ) ), receiver, slot );
880}
881
882KListAction::KListAction( const QString& text, const QString& pix,
883 const KShortcut& cut, const QObject* receiver,
884 const char* slot, QObject* parent,
885 const char* name )
886 : KSelectAction( text, pix, cut, parent, name )
887{
888 d = new KListActionPrivate;
889 if ( receiver )
890 connect( this, SIGNAL( activated( int ) ), receiver, slot );
891}
892
893KListAction::KListAction( QObject* parent, const char* name )
894 : KSelectAction( parent, name )
895{
896 d = new KListActionPrivate;
897}
898
899KListAction::~KListAction()
900{
901 delete d; d = 0;
902}
903
904void KListAction::setCurrentItem( int index )
905{
906 KSelectAction::setCurrentItem( index );
907 d->m_current = index;
908
909 // emit KAction::activated();
910 // emit activated( currentItem() );
911 // emit activated( currentText() );
912}
913
914QString KListAction::currentText() const
915{
916 if ( currentItem() < 0 )
917 return QString::null;
918
919 return items()[ currentItem() ];
920}
921
922int KListAction::currentItem() const
923{
924 return d->m_current;
925}
926
927class KRecentFilesAction::KRecentFilesActionPrivate
928{
929public:
930 KRecentFilesActionPrivate()
931 {
932 m_maxItems = 0;
933 }
934 uint m_maxItems;
935};
936
937KRecentFilesAction::KRecentFilesAction( const QString& text,
938 const KShortcut& cut,
939 QObject* parent, const char* name,
940 uint maxItems )
941 : KListAction( text, cut, parent, name)
942{
943 d = new KRecentFilesActionPrivate;
944 d->m_maxItems = maxItems;
945
946 init();
947}
948
949KRecentFilesAction::KRecentFilesAction( const QString& text,
950 const KShortcut& cut,
951 const QObject* receiver,
952 const char* slot,
953 QObject* parent, const char* name,
954 uint maxItems )
955 : KListAction( text, cut, parent, name)
956{
957 d = new KRecentFilesActionPrivate;
958 d->m_maxItems = maxItems;
959
960 init();
961
962 if ( receiver )
963 connect( this, SIGNAL(urlSelected(const KURL&)),
964 receiver, slot );
965}
966
967KRecentFilesAction::KRecentFilesAction( const QString& text,
968 const QIconSet& pix,
969 const KShortcut& cut,
970 QObject* parent, const char* name,
971 uint maxItems )
972 : KListAction( text, pix, cut, parent, name)
973{
974 d = new KRecentFilesActionPrivate;
975 d->m_maxItems = maxItems;
976
977 init();
978}
979
980KRecentFilesAction::KRecentFilesAction( const QString& text,
981 const QString& pix,
982 const KShortcut& cut,
983 QObject* parent, const char* name,
984 uint maxItems )
985 : KListAction( text, pix, cut, parent, name)
986{
987 d = new KRecentFilesActionPrivate;
988 d->m_maxItems = maxItems;
989
990 init();
991}
992
993KRecentFilesAction::KRecentFilesAction( const QString& text,
994 const QIconSet& pix,
995 const KShortcut& cut,
996 const QObject* receiver,
997 const char* slot,
998 QObject* parent, const char* name,
999 uint maxItems )
1000 : KListAction( text, pix, cut, parent, name)
1001{
1002 d = new KRecentFilesActionPrivate;
1003 d->m_maxItems = maxItems;
1004
1005 init();
1006
1007 if ( receiver )
1008 connect( this, SIGNAL(urlSelected(const KURL&)),
1009 receiver, slot );
1010}
1011
1012KRecentFilesAction::KRecentFilesAction( const QString& text,
1013 const QString& pix,
1014 const KShortcut& cut,
1015 const QObject* receiver,
1016 const char* slot,
1017 QObject* parent, const char* name,
1018 uint maxItems )
1019 : KListAction( text, pix, cut, parent, name)
1020{
1021 d = new KRecentFilesActionPrivate;
1022 d->m_maxItems = maxItems;
1023
1024 init();
1025
1026 if ( receiver )
1027 connect( this, SIGNAL(urlSelected(const KURL&)),
1028 receiver, slot );
1029}
1030
1031KRecentFilesAction::KRecentFilesAction( QObject* parent, const char* name,
1032 uint maxItems )
1033 : KListAction( parent, name )
1034{
1035 d = new KRecentFilesActionPrivate;
1036 d->m_maxItems = maxItems;
1037
1038 init();
1039}
1040
1041void KRecentFilesAction::init()
1042{
1043 connect( this, SIGNAL( activated( const QString& ) ),
1044 this, SLOT( itemSelected( const QString& ) ) );
1045
1046 setMenuAccelsEnabled( false );
1047}
1048
1049KRecentFilesAction::~KRecentFilesAction()
1050{
1051 delete d; d = 0;
1052}
1053
1054uint KRecentFilesAction::maxItems() const
1055{
1056 return d->m_maxItems;
1057}
1058
1059void KRecentFilesAction::setMaxItems( uint maxItems )
1060{
1061 QStringList lst = items();
1062 uint oldCount = lst.count();
1063
1064 // set new maxItems
1065 d->m_maxItems = maxItems;
1066
1067 // remove all items that are too much
1068 while( lst.count() > maxItems )
1069 {
1070 // remove last item
1071 lst.remove( lst.last() );
1072 }
1073
1074 // set new list if changed
1075 if( lst.count() != oldCount )
1076 setItems( lst );
1077}
1078
1079void KRecentFilesAction::addURL( const KURL& url )
1080{
1081 QString file = url.prettyURL();
1082 QStringList lst = items();
1083
1084 // remove file if already in list
1085 lst.remove( file );
1086
1087 // remove las item if already maxitems in list
1088 if( lst.count() == d->m_maxItems )
1089 {
1090 // remove last item
1091 lst.remove( lst.last() );
1092 }
1093
1094 // add file to list
1095 lst.prepend( file );
1096 setItems( lst );
1097}
1098
1099void KRecentFilesAction::removeURL( const KURL& url )
1100{
1101 QStringList lst = items();
1102 QString file = url.prettyURL();
1103
1104 // remove url
1105 if( lst.count() > 0 )
1106 {
1107 lst.remove( file );
1108 setItems( lst );
1109 }
1110}
1111
1112void KRecentFilesAction::clearURLList()
1113{
1114 clear();
1115}
1116
1117void KRecentFilesAction::loadEntries( KConfig* config, QString groupname)
1118{
1119 QString key;
1120 QString value;
1121 QString oldGroup;
1122 QStringList lst;
1123
1124 oldGroup = config->group();
1125
1126 if (groupname.isEmpty())
1127 groupname = "RecentFiles";
1128 config->setGroup( groupname );
1129
1130 // read file list
1131 for( unsigned int i = 1 ; i <= d->m_maxItems ; i++ )
1132 {
1133 key = QString( "File%1" ).arg( i );
1134 value = config->readEntry( key, QString::null );
1135
1136 if (!value.isNull())
1137 lst.append( value );
1138 }
1139
1140 // set file
1141 setItems( lst );
1142
1143 config->setGroup( oldGroup );
1144}
1145
1146void KRecentFilesAction::saveEntries( KConfig* config, QString groupname )
1147{
1148 QString key;
1149 QString value;
1150 QStringList lst = items();
1151
1152 if (groupname.isEmpty())
1153 groupname = "RecentFiles";
1154
1155 config->deleteGroup( groupname);
1156
1157 KConfigGroupSaver( config, groupname );
1158
1159 // write file list
1160 for( unsigned int i = 1 ; i <= lst.count() ; i++ )
1161 {
1162 key = QString( "File%1" ).arg( i );
1163 value = lst[ i - 1 ];
1164 config->writeEntry( key, value );
1165 }
1166}
1167
1168void KRecentFilesAction::itemSelected( const QString& text )
1169{
1170 emit urlSelected( KURL( text ) );
1171}
1172
1173class KFontAction::KFontActionPrivate
1174{
1175public:
1176 KFontActionPrivate()
1177 {
1178 }
1179 QStringList m_fonts;
1180};
1181
1182KFontAction::KFontAction( const QString& text,
1183 const KShortcut& cut, QObject* parent,
1184 const char* name )
1185 : KSelectAction( text, cut, parent, name )
1186{
1187 d = new KFontActionPrivate;
1188 get_fonts( d->m_fonts );
1189 KSelectAction::setItems( d->m_fonts );
1190 setEditable( true );
1191}
1192
1193KFontAction::KFontAction( const QString& text, const KShortcut& cut,
1194 const QObject* receiver, const char* slot,
1195 QObject* parent, const char* name )
1196 : KSelectAction( text, cut, receiver, slot, parent, name )
1197{
1198 d = new KFontActionPrivate;
1199 get_fonts( d->m_fonts );
1200 KSelectAction::setItems( d->m_fonts );
1201 setEditable( true );
1202}
1203
1204KFontAction::KFontAction( const QString& text, const QIconSet& pix,
1205 const KShortcut& cut,
1206 QObject* parent, const char* name )
1207 : KSelectAction( text, pix, cut, parent, name )
1208{
1209 d = new KFontActionPrivate;
1210 get_fonts( d->m_fonts );
1211 KSelectAction::setItems( d->m_fonts );
1212 setEditable( true );
1213}
1214
1215KFontAction::KFontAction( const QString& text, const QString& pix,
1216 const KShortcut& cut,
1217 QObject* parent, const char* name )
1218 : KSelectAction( text, pix, cut, parent, name )
1219{
1220 d = new KFontActionPrivate;
1221 get_fonts( d->m_fonts );
1222 KSelectAction::setItems( d->m_fonts );
1223 setEditable( true );
1224}
1225
1226KFontAction::KFontAction( const QString& text, const QIconSet& pix,
1227 const KShortcut& cut,
1228 const QObject* receiver, const char* slot,
1229 QObject* parent, const char* name )
1230 : KSelectAction( text, pix, cut, receiver, slot, parent, name )
1231{
1232 d = new KFontActionPrivate;
1233 get_fonts( d->m_fonts );
1234 KSelectAction::setItems( d->m_fonts );
1235 setEditable( true );
1236}
1237
1238KFontAction::KFontAction( const QString& text, const QString& pix,
1239 const KShortcut& cut,
1240 const QObject* receiver, const char* slot,
1241 QObject* parent, const char* name )
1242 : KSelectAction( text, pix, cut, receiver, slot, parent, name )
1243{
1244 d = new KFontActionPrivate;
1245 get_fonts( d->m_fonts );
1246 KSelectAction::setItems( d->m_fonts );
1247 setEditable( true );
1248}
1249
1250
1251KFontAction::KFontAction( QObject* parent, const char* name )
1252 : KSelectAction( parent, name )
1253{
1254 d = new KFontActionPrivate;
1255 get_fonts( d->m_fonts );
1256 KSelectAction::setItems( d->m_fonts );
1257 setEditable( true );
1258}
1259
1260KFontAction::~KFontAction()
1261{
1262 delete d;
1263 d = 0;
1264}
1265
1266/*
1267 * Maintenance note: Keep in sync with KFontCombo::setCurrentFont()
1268 */
1269void KFontAction::setFont( const QString &family )
1270{
1271 QString lowerName = family.lower();
1272 int i = 0;
1273 for ( QStringList::Iterator it = d->m_fonts.begin(); it != d->m_fonts.end(); ++it, ++i )
1274 {
1275 if ((*it).lower() == lowerName)
1276 {
1277 setCurrentItem(i);
1278 return;
1279 }
1280 }
1281 i = lowerName.find(" [");
1282 if (i>-1)
1283 {
1284 lowerName = lowerName.left(i);
1285 i = 0;
1286 for ( QStringList::Iterator it = d->m_fonts.begin(); it != d->m_fonts.end(); ++it, ++i )
1287 {
1288 if ((*it).lower() == lowerName)
1289 {
1290 setCurrentItem(i);
1291 return;
1292 }
1293 }
1294 }
1295
1296 lowerName += " [";
1297 i = 0;
1298 for ( QStringList::Iterator it = d->m_fonts.begin(); it != d->m_fonts.end(); ++it, ++i )
1299 {
1300 if ((*it).lower().startsWith(lowerName))
1301 {
1302 setCurrentItem(i);
1303 return;
1304 }
1305 }
1306 kdDebug(129) << "Font not found " << family.lower() << endl;
1307}
1308
1309int KFontAction::plug( QWidget *w, int index )
1310{
1311 qDebug("KFontAction::plug ha to be fixed");
1312/*US
1313 if (kapp && !kapp->authorizeKAction(name()))
1314 return -1;
1315 if ( w->inherits("KToolBar") )
1316 {
1317 KToolBar* bar = static_cast<KToolBar*>( w );
1318 int id_ = KAction::getToolButtonID();
1319 KFontCombo *cb = new KFontCombo( items(), bar );
1320 connect( cb, SIGNAL( activated( const QString & ) ),
1321 SLOT( slotActivated( const QString & ) ) );
1322 cb->setEnabled( isEnabled() );
1323 bar->insertWidget( id_, comboWidth(), cb, index );
1324 cb->setMinimumWidth( cb->sizeHint().width() );
1325
1326 addContainer( bar, id_ );
1327
1328 connect( bar, SIGNAL( destroyed() ), this, SLOT( slotDestroyed() ) );
1329
1330 updateCurrentItem( containerCount() - 1 );
1331
1332 return containerCount() - 1;
1333 }
1334 else return KSelectAction::plug( w, index );
1335*/
1336 return 3;
1337}
1338
1339class KFontSizeAction::KFontSizeActionPrivate
1340{
1341public:
1342 KFontSizeActionPrivate()
1343 {
1344 }
1345};
1346
1347KFontSizeAction::KFontSizeAction( const QString& text,
1348 const KShortcut& cut,
1349 QObject* parent, const char* name )
1350 : KSelectAction( text, cut, parent, name )
1351{
1352 init();
1353}
1354
1355KFontSizeAction::KFontSizeAction( const QString& text,
1356 const KShortcut& cut,
1357 const QObject* receiver, const char* slot,
1358 QObject* parent, const char* name )
1359 : KSelectAction( text, cut, receiver, slot, parent, name )
1360{
1361 init();
1362}
1363
1364KFontSizeAction::KFontSizeAction( const QString& text, const QIconSet& pix,
1365 const KShortcut& cut,
1366 QObject* parent, const char* name )
1367 : KSelectAction( text, pix, cut, parent, name )
1368{
1369 init();
1370}
1371
1372KFontSizeAction::KFontSizeAction( const QString& text, const QString& pix,
1373 const KShortcut& cut,
1374 QObject* parent, const char* name )
1375 : KSelectAction( text, pix, cut, parent, name )
1376{
1377 init();
1378}
1379
1380KFontSizeAction::KFontSizeAction( const QString& text, const QIconSet& pix,
1381 const KShortcut& cut,
1382 const QObject* receiver,
1383 const char* slot, QObject* parent,
1384 const char* name )
1385 : KSelectAction( text, pix, cut, receiver, slot, parent, name )
1386{
1387 init();
1388}
1389
1390KFontSizeAction::KFontSizeAction( const QString& text, const QString& pix,
1391 const KShortcut& cut,
1392 const QObject* receiver,
1393 const char* slot, QObject* parent,
1394 const char* name )
1395 : KSelectAction( text, pix, cut, receiver, slot, parent, name )
1396{
1397 init();
1398}
1399
1400KFontSizeAction::KFontSizeAction( QObject* parent, const char* name )
1401 : KSelectAction( parent, name )
1402{
1403 init();
1404}
1405
1406KFontSizeAction::~KFontSizeAction()
1407{
1408 delete d;
1409 d = 0;
1410}
1411
1412void KFontSizeAction::init()
1413{
1414 d = new KFontSizeActionPrivate;
1415
1416 setEditable( true );
1417 QValueList<int> sizes = get_standard_font_sizes();
1418 QStringList lst;
1419 for ( QValueList<int>::Iterator it = sizes.begin(); it != sizes.end(); ++it )
1420 lst.append( QString::number( *it ) );
1421
1422 setItems( lst );
1423}
1424
1425void KFontSizeAction::setFontSize( int size )
1426{
1427 if ( size == fontSize() ) {
1428 setCurrentItem( items().findIndex( QString::number( size ) ) );
1429 return;
1430 }
1431
1432 if ( size < 1 ) {
1433 kdWarning() << "KFontSizeAction: Size " << size << " is out of range" << endl;
1434 return;
1435 }
1436
1437 int index = items().findIndex( QString::number( size ) );
1438 if ( index == -1 ) {
1439 // Insert at the correct position in the list (to keep sorting)
1440 QValueList<int> lst;
1441 // Convert to list of ints
1442 QStringList itemsList = items();
1443 for (QStringList::Iterator it = itemsList.begin() ; it != itemsList.end() ; ++it)
1444 lst.append( (*it).toInt() );
1445 // New size
1446 lst.append( size );
1447 // Sort the list
1448qDebug("KFontSizeAction::setFontSize heapsort not found.");
1449//US has to be fixed
1450//US qHeapSort( lst );
1451 // Convert back to string list
1452 QStringList strLst;
1453 for (QValueList<int>::Iterator it = lst.begin() ; it != lst.end() ; ++it)
1454 strLst.append( QString::number(*it) );
1455 KSelectAction::setItems( strLst );
1456 // Find new current item
1457 index = lst.findIndex( size );
1458 setCurrentItem( index );
1459 }
1460 else
1461 setCurrentItem( index );
1462
1463
1464 //emit KAction::activated();
1465 //emit activated( index );
1466 //emit activated( QString::number( size ) );
1467 //emit fontSizeChanged( size );
1468}
1469
1470int KFontSizeAction::fontSize() const
1471{
1472 return currentText().toInt();
1473}
1474
1475void KFontSizeAction::slotActivated( int index )
1476{
1477 KSelectAction::slotActivated( index );
1478
1479 emit fontSizeChanged( items()[ index ].toInt() );
1480}
1481
1482void KFontSizeAction::slotActivated( const QString& size )
1483{
1484 setFontSize( size.toInt() ); // insert sorted first
1485 KSelectAction::slotActivated( size );
1486 emit fontSizeChanged( size.toInt() );
1487}
1488
1489class KActionMenu::KActionMenuPrivate
1490{
1491public:
1492 KActionMenuPrivate()
1493 {
1494//US m_popup = new KPopupMenu(0L,"KActionMenu::KActionMenuPrivate");
1495 m_popup = new QPopupMenu(0L,"KActionMenu::KActionMenuPrivate");
1496 m_delayed = true;
1497 m_stickyMenu = true;
1498 }
1499 ~KActionMenuPrivate()
1500 {
1501 delete m_popup; m_popup = 0;
1502 }
1503
1504//US KPopupMenu *m_popup;
1505 QPopupMenu *m_popup;
1506 bool m_delayed;
1507 bool m_stickyMenu;
1508};
1509
1510KActionMenu::KActionMenu( QObject* parent, const char* name )
1511 : KAction( parent, name )
1512{
1513 d = new KActionMenuPrivate;
1514 setShortcutConfigurable( false );
1515}
1516
1517KActionMenu::KActionMenu( const QString& text, QObject* parent,
1518 const char* name )
1519 : KAction( text, 0, parent, name )
1520{
1521 d = new KActionMenuPrivate;
1522 setShortcutConfigurable( false );
1523}
1524
1525KActionMenu::KActionMenu( const QString& text, const QIconSet& icon,
1526 QObject* parent, const char* name )
1527 : KAction( text, icon, 0, parent, name )
1528{
1529 d = new KActionMenuPrivate;
1530 setShortcutConfigurable( false );
1531}
1532
1533KActionMenu::KActionMenu( const QString& text, const QString& icon,
1534 QObject* parent, const char* name )
1535 : KAction( text, icon, 0, parent, name )
1536{
1537 d = new KActionMenuPrivate;
1538 setShortcutConfigurable( false );
1539}
1540
1541KActionMenu::~KActionMenu()
1542{
1543 unplugAll();
1544 kdDebug(129) << "KActionMenu::~KActionMenu()" << endl; // ellis
1545 delete d; d = 0;
1546}
1547
1548void KActionMenu::popup( const QPoint& global )
1549{
1550 popupMenu()->popup( global );
1551}
1552
1553
1554//US KPopupMenu* KActionMenu::popupMenu() const
1555QPopupMenu* KActionMenu::popupMenu() const
1556{
1557 return d->m_popup;
1558}
1559
1560void KActionMenu::insert( KAction* cmd, int index )
1561{
1562 if ( cmd )
1563 cmd->plug( d->m_popup, index );
1564}
1565
1566void KActionMenu::remove( KAction* cmd )
1567{
1568 if ( cmd )
1569 cmd->unplug( d->m_popup );
1570}
1571
1572bool KActionMenu::delayed() const {
1573 return d->m_delayed;
1574}
1575
1576void KActionMenu::setDelayed(bool _delayed) {
1577 d->m_delayed = _delayed;
1578}
1579
1580bool KActionMenu::stickyMenu() const {
1581 return d->m_stickyMenu;
1582}
1583
1584void KActionMenu::setStickyMenu(bool sticky) {
1585 d->m_stickyMenu = sticky;
1586}
1587
1588int KActionMenu::plug( QWidget* widget, int index )
1589{
1590/*US
1591 if (kapp && !kapp->authorizeKAction(name()))
1592 return -1;
1593*/
1594 kdDebug(129) << "KAction::plug( " << widget << ", " << index << " )" << endl; // remove -- ellis
1595 if ( widget->inherits("QPopupMenu") )
1596 {
1597 QPopupMenu* menu = static_cast<QPopupMenu*>( widget );
1598 int id;
1599 if ( hasIconSet() )
1600 id = menu->insertItem( iconSet(), text(), d->m_popup, -1, index );
1601 else
1602 id = menu->insertItem( text(), d->m_popup, -1, index );
1603
1604 if ( !isEnabled() )
1605 menu->setItemEnabled( id, false );
1606
1607 addContainer( menu, id );
1608 connect( menu, SIGNAL( destroyed() ), this, SLOT( slotDestroyed() ) );
1609
1610 if ( m_parentCollection )
1611 m_parentCollection->connectHighlight( menu, this );
1612
1613 return containerCount() - 1;
1614 }
1615 else if ( widget->inherits( "KToolBar" ) )
1616 {
1617 KToolBar *bar = static_cast<KToolBar *>( widget );
1618
1619 int id_ = KAction::getToolButtonID();
1620
1621 if ( icon().isEmpty() && !iconSet().isNull() )
1622 bar->insertButton( iconSet().pixmap(), id_, SIGNAL( clicked() ), this,
1623 SLOT( slotActivated() ), isEnabled(), plainText(),
1624 index );
1625 else
1626 {
1627 /*US
1628 KInstance *instance;
1629
1630 if ( m_parentCollection )
1631 instance = m_parentCollection->instance();
1632 else
1633 instance = KGlobal::instance();
1634*/
1635 bar->insertButton( icon(), id_, SIGNAL( clicked() ), this,
1636 SLOT( slotActivated() ), isEnabled(), plainText(),
1637 index/*US, instance */);
1638 }
1639
1640 addContainer( bar, id_ );
1641/*US
1642 if (!whatsThis().isEmpty())
1643 QWhatsThis::add( bar->getButton(id_), whatsThis() );
1644*/
1645 connect( bar, SIGNAL( destroyed() ), this, SLOT( slotDestroyed() ) );
1646
1647 if (delayed()) {
1648 bar->setDelayedPopup( id_, popupMenu(), stickyMenu() );
1649 } else {
1650 bar->getButton(id_)->setPopup(popupMenu(), stickyMenu() );
1651 }
1652
1653 if ( m_parentCollection )
1654 m_parentCollection->connectHighlight( bar, this );
1655
1656 return containerCount() - 1;
1657 }
1658 else if ( widget->inherits( "QMenuBar" ) )
1659 {
1660 QMenuBar *bar = static_cast<QMenuBar *>( widget );
1661
1662 int id;
1663
1664 id = bar->insertItem( text(), popupMenu(), -1, index );
1665
1666 if ( !isEnabled() )
1667 bar->setItemEnabled( id, false );
1668
1669 addContainer( bar, id );
1670 connect( bar, SIGNAL( destroyed() ), this, SLOT( slotDestroyed() ) );
1671
1672 return containerCount() - 1;
1673 }
1674
1675 return -1;
1676}
1677
1678////////
1679
1680KToolBarPopupAction::KToolBarPopupAction( const QString& text,
1681 const QString& icon,
1682 const KShortcut& cut,
1683 QObject* parent, const char* name )
1684 : KAction( text, icon, cut, parent, name )
1685{
1686 m_popup = 0;
1687 m_delayed = true;
1688 m_stickyMenu = true;
1689}
1690
1691KToolBarPopupAction::KToolBarPopupAction( const QString& text,
1692 const QString& icon,
1693 const KShortcut& cut,
1694 const QObject* receiver,
1695 const char* slot, QObject* parent,
1696 const char* name )
1697 : KAction( text, icon, cut, receiver, slot, parent, name )
1698{
1699 m_popup = 0;
1700 m_delayed = true;
1701 m_stickyMenu = true;
1702}
1703
1704KToolBarPopupAction::KToolBarPopupAction( const KGuiItem& item,
1705 const KShortcut& cut,
1706 const QObject* receiver,
1707 const char* slot, KActionCollection* parent,
1708 const char* name )
1709 : KAction( item, cut, receiver, slot, parent, name )
1710{
1711 m_popup = 0;
1712 m_delayed = true;
1713 m_stickyMenu = true;
1714}
1715
1716
1717KToolBarPopupAction::~KToolBarPopupAction()
1718{
1719 if ( m_popup )
1720 delete m_popup;
1721}
1722
1723bool KToolBarPopupAction::delayed() const {
1724 return m_delayed;
1725}
1726
1727void KToolBarPopupAction::setDelayed(bool delayed) {
1728 m_delayed = delayed;
1729}
1730
1731bool KToolBarPopupAction::stickyMenu() const {
1732 return m_stickyMenu;
1733}
1734
1735void KToolBarPopupAction::setStickyMenu(bool sticky) {
1736 m_stickyMenu = sticky;
1737}
1738
1739int KToolBarPopupAction::plug( QWidget *widget, int index )
1740{
1741/*US
1742 if (kapp && !kapp->authorizeKAction(name()))
1743 return -1;
1744*/
1745 // This is very related to KActionMenu::plug.
1746 // In fact this class could be an interesting base class for KActionMenu
1747 if ( widget->inherits( "KToolBar" ) )
1748 {
1749 KToolBar *bar = (KToolBar *)widget;
1750
1751 int id_ = KAction::getToolButtonID();
1752/*US
1753 KInstance * instance;
1754 if ( m_parentCollection )
1755 instance = m_parentCollection->instance();
1756 else
1757 instance = KGlobal::instance();
1758*/
1759 bar->insertButton( icon(), id_, SIGNAL( clicked() ), this,
1760 SLOT( slotActivated() ), isEnabled(), plainText(),
1761 index/*US, instance*/ );
1762
1763 addContainer( bar, id_ );
1764
1765 connect( bar, SIGNAL( destroyed() ), this, SLOT( slotDestroyed() ) );
1766
1767 if (delayed()) {
1768 bar->setDelayedPopup( id_, popupMenu(), stickyMenu() );
1769 } else {
1770 bar->getButton(id_)->setPopup(popupMenu(), stickyMenu());
1771 }
1772/*US
1773 if ( !whatsThis().isEmpty() )
1774 QWhatsThis::add( bar->getButton( id_ ), whatsThisWithIcon() );
1775*/
1776 return containerCount() - 1;
1777 }
1778
1779
1780 return KAction::plug( widget, index );
1781}
1782
1783//US KPopupMenu *KToolBarPopupAction::popupMenu() const
1784QPopupMenu *KToolBarPopupAction::popupMenu() const
1785{
1786 if ( !m_popup ) {
1787 KToolBarPopupAction *that = const_cast<KToolBarPopupAction*>(this);
1788//US that->m_popup = new KPopupMenu;
1789 that->m_popup = new QPopupMenu;
1790 }
1791 return m_popup;
1792}
1793
1794////////
1795
1796KToggleToolBarAction::KToggleToolBarAction( const char* toolBarName,
1797 const QString& text, KActionCollection* parent, const char* name )
1798 : KToggleAction( text, KShortcut(), parent, name )
1799 , m_toolBarName( toolBarName )
1800 , m_toolBar( 0L )
1801{
1802}
1803
1804KToggleToolBarAction::KToggleToolBarAction( KToolBar *toolBar, const QString &text,
1805 KActionCollection *parent, const char *name )
1806 : KToggleAction( text, KShortcut(), parent, name )
1807 , m_toolBarName( 0 )
1808 , m_toolBar( toolBar )
1809{
1810}
1811
1812KToggleToolBarAction::~KToggleToolBarAction()
1813{
1814}
1815
1816int KToggleToolBarAction::plug( QWidget* w, int index )
1817{
1818 qDebug("KToggleToolBarAction::plug has to be fixed");
1819/*US
1820 if (kapp && !kapp->authorizeKAction(name()))
1821 return -1;
1822
1823 if ( !m_toolBar ) {
1824 // Note: topLevelWidget() stops too early, we can't use it.
1825 QWidget * tl = w;
1826 QWidget * n;
1827 while ( !tl->isDialog() && ( n = tl->parentWidget() ) ) // lookup parent and store
1828 tl = n;
1829
1830//US KMainWindow * mw = dynamic_cast<KMainWindow *>(tl); // try to see if it's a kmainwindow
1831 QMainWindow * mw = 0;
1832 if ( tl->inherits("QMainWindow") )
1833 mw = (QMainWindow *)(tl); // try to see if it's a kmainwindow
1834
1835 if ( mw )
1836 m_toolBar = mw->toolBar( m_toolBarName );
1837 }
1838
1839 if( m_toolBar ) {
1840 setChecked( m_toolBar->isVisible() );
1841 connect( m_toolBar, SIGNAL(visibilityChanged(bool)), this, SLOT(setChecked(bool)) );
1842 // Also emit toggled when the toolbar's visibility changes (see comment in header)
1843 connect( m_toolBar, SIGNAL(visibilityChanged(bool)), this, SIGNAL(toggled(bool)) );
1844 } else {
1845 setEnabled( false );
1846 }
1847*/
1848 return KToggleAction::plug( w, index );
1849}
1850
1851void KToggleToolBarAction::setChecked( bool c )
1852{
1853 if( m_toolBar && c != m_toolBar->isVisible() ) {
1854 if( c ) {
1855 m_toolBar->show();
1856 } else {
1857 m_toolBar->hide();
1858 }
1859 qDebug("KToggleToolBarAction::setChecked has to be fixed");
1860/*US
1861 QMainWindow* mw = m_toolBar->mainWindow();
1862 if ( mw && mw->inherits( "KMainWindow" ) )
1863 static_cast<KMainWindow *>( mw )->setSettingsDirty();
1864*/
1865 }
1866 KToggleAction::setChecked( c );
1867
1868}
1869
1870////////
1871
1872KWidgetAction::KWidgetAction( QWidget* widget,
1873 const QString& text, const KShortcut& cut,
1874 const QObject* receiver, const char* slot,
1875 KActionCollection* parent, const char* name )
1876 : KAction( text, cut, receiver, slot, parent, name )
1877 , m_widget( widget )
1878 , m_autoSized( false )
1879{
1880}
1881
1882KWidgetAction::~KWidgetAction()
1883{
1884}
1885
1886void KWidgetAction::setAutoSized( bool autoSized )
1887{
1888 if( m_autoSized == autoSized )
1889 return;
1890
1891 m_autoSized = autoSized;
1892
1893 if( !m_widget || !isPlugged() )
1894 return;
1895
1896 KToolBar* toolBar = (KToolBar*)m_widget->parent();
1897 int i = findContainer( toolBar );
1898 if ( i == -1 )
1899 return;
1900 int id = itemId( i );
1901
1902 toolBar->setItemAutoSized( id, m_autoSized );
1903
1904}
1905
1906int KWidgetAction::plug( QWidget* w, int index )
1907{
1908/*US
1909 if (kapp && !kapp->authorizeKAction(name()))
1910 return -1;
1911*/
1912 if ( !w->inherits( "KToolBar" ) ) {
1913 kdError() << "KWidgetAction::plug: KWidgetAction must be plugged into KToolBar." << endl;
1914 return -1;
1915 }
1916 if ( !m_widget ) {
1917 kdError() << "KWidgetAction::plug: Widget was deleted or null!" << endl;
1918 return -1;
1919 }
1920
1921 KToolBar* toolBar = static_cast<KToolBar*>( w );
1922
1923 int id = KAction::getToolButtonID();
1924
1925 m_widget->reparent( toolBar, QPoint() );
1926 toolBar->insertWidget( id, 0, m_widget, index );
1927 toolBar->setItemAutoSized( id, m_autoSized );
1928
1929//US QWhatsThis::add( m_widget, whatsThis() );
1930 addContainer( toolBar, id );
1931
1932 connect( toolBar, SIGNAL( toolbarDestroyed() ), this, SLOT( slotToolbarDestroyed() ) );
1933 connect( toolBar, SIGNAL( destroyed() ), this, SLOT( slotDestroyed() ) );
1934
1935 return containerCount() - 1;
1936}
1937
1938void KWidgetAction::unplug( QWidget *w )
1939{
1940 if( !m_widget || !isPlugged() )
1941 return;
1942
1943 KToolBar* toolBar = (KToolBar*)m_widget->parent();
1944 if ( toolBar == w )
1945 {
1946 disconnect( toolBar, SIGNAL( toolbarDestroyed() ), this, SLOT( slotToolbarDestroyed() ) );
1947 m_widget->reparent( 0L, QPoint(), false ); // false = showit
1948 }
1949 KAction::unplug( w );
1950}
1951
1952void KWidgetAction::slotToolbarDestroyed()
1953{
1954 //Q_ASSERT( m_widget ); // When exiting the app the widget could be destroyed before the toolbar.
1955
1956 ASSERT( isPlugged() );
1957 if( !m_widget || !isPlugged() )
1958 return;
1959
1960 // Don't let a toolbar being destroyed, delete my widget.
1961 m_widget->reparent( 0L, QPoint(), false /*showIt*/ );
1962}
1963
1964////////
1965
1966KActionSeparator::KActionSeparator( QObject *parent, const char *name )
1967 : KAction( parent, name )
1968{
1969}
1970
1971KActionSeparator::~KActionSeparator()
1972{
1973}
1974
1975int KActionSeparator::plug( QWidget *widget, int index )
1976{
1977 if ( widget->inherits("QPopupMenu") )
1978 {
1979 QPopupMenu* menu = static_cast<QPopupMenu*>( widget );
1980
1981 int id = menu->insertSeparator( index );
1982
1983 addContainer( menu, id );
1984 connect( menu, SIGNAL( destroyed() ), this, SLOT( slotDestroyed() ) );
1985
1986 return containerCount() - 1;
1987 }
1988 else if ( widget->inherits( "QMenuBar" ) )
1989 {
1990 QMenuBar *menuBar = static_cast<QMenuBar *>( widget );
1991
1992 int id = menuBar->insertSeparator( index );
1993
1994 addContainer( menuBar, id );
1995
1996 connect( menuBar, SIGNAL( destroyed() ), this, SLOT( slotDestroyed() ) );
1997
1998 return containerCount() - 1;
1999 }
2000 else if ( widget->inherits( "KToolBar" ) )
2001 {
2002 KToolBar *toolBar = static_cast<KToolBar *>( widget );
2003
2004 int id = toolBar->insertSeparator( index );
2005// toolBar->addSeparator();
2006
2007 addContainer( toolBar, id );
2008
2009 connect( toolBar, SIGNAL( destroyed() ), this, SLOT( slotDestroyed() ) );
2010
2011 return containerCount() - 1;
2012 }
2013
2014 return -1;
2015}
2016
2017void KToggleAction::virtual_hook( int id, void* data )
2018{ KAction::virtual_hook( id, data ); }
2019
2020void KRadioAction::virtual_hook( int id, void* data )
2021{ KToggleAction::virtual_hook( id, data ); }
2022
2023void KSelectAction::virtual_hook( int id, void* data )
2024{ KAction::virtual_hook( id, data ); }
2025
2026void KListAction::virtual_hook( int id, void* data )
2027{ KSelectAction::virtual_hook( id, data ); }
2028
2029void KRecentFilesAction::virtual_hook( int id, void* data )
2030{ KListAction::virtual_hook( id, data ); }
2031
2032void KFontAction::virtual_hook( int id, void* data )
2033{ KSelectAction::virtual_hook( id, data ); }
2034
2035void KFontSizeAction::virtual_hook( int id, void* data )
2036{ KSelectAction::virtual_hook( id, data ); }
2037
2038void KActionMenu::virtual_hook( int id, void* data )
2039{ KAction::virtual_hook( id, data ); }
2040
2041void KToolBarPopupAction::virtual_hook( int id, void* data )
2042{ KAction::virtual_hook( id, data ); }
2043
2044void KToggleToolBarAction::virtual_hook( int id, void* data )
2045{ KToggleAction::virtual_hook( id, data ); }
2046
2047void KWidgetAction::virtual_hook( int id, void* data )
2048{ KAction::virtual_hook( id, data ); }
2049
2050void KActionSeparator::virtual_hook( int id, void* data )
2051{ KAction::virtual_hook( id, data ); }
2052
2053/* vim: et sw=2 ts=2
2054 */
2055
2056/*US
2057#include "kactionclasses.moc"
2058*/
diff --git a/microkde/kdeui/kactionclasses.h b/microkde/kdeui/kactionclasses.h
new file mode 100644
index 0000000..f6e7a0f
--- a/dev/null
+++ b/microkde/kdeui/kactionclasses.h
@@ -0,0 +1,1223 @@
1/* This file is part of the KDE libraries
2 Copyright (C) 1999 Reginald Stadlbauer <reggie@kde.org>
3 (C) 1999 Simon Hausmann <hausmann@kde.org>
4 (C) 2000 Nicolas Hadacek <haadcek@kde.org>
5 (C) 2000 Kurt Granroth <granroth@kde.org>
6 (C) 2000 Michael Koch <koch@kde.org>
7 (C) 2001 Holger Freyther <freyther@kde.org>
8 (C) 2002 Ellis Whitehead <ellis@kde.org>
9
10 This library is free software; you can redistribute it and/or
11 modify it under the terms of the GNU Library General Public
12 License version 2 as published by the Free Software Foundation.
13
14 This library is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Library General Public License for more details.
18
19 You should have received a copy of the GNU Library General Public License
20 along with this library; see the file COPYING.LIB. If not, write to
21 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22 Boston, MA 02111-1307, USA.
23*/
24//$Id$
25
26#ifndef __kactionclasses_h__
27#define __kactionclasses_h__
28
29#include <kaction.h>
30
31//US#include <qkeysequence.h>
32//US#include <qobject.h>
33//US#include <qvaluelist.h>
34//US#include <qguardedptr.h>
35//US#include <kguiitem.h>
36#include <kshortcut.h>
37//US#include <kstdaction.h>
38//US#include <kicontheme.h>
39
40class QMenuBar;
41class QPopupMenu;
42//USclass QComboBox;
43//USclass QPoint;
44//USclass QIconSet;
45//USclass QString;
46//USclass KToolBar;
47
48//USclass KAccel;
49//USclass KAccelActions;
50class KConfig;
51//USclass KConfigBase;
52class KURL;
53//USclass KInstance;
54
55
56//US class KToolBar needs to be replaced
57class KToolBar;
58class KActionCollection;
59
60//US class KPopupMenu needs to be replaced
61//US class KPopupMenu;
62//USclass KMainWindow;
63
64/**
65 * Checkbox like action.
66 *
67 * This action provides two states: checked or not.
68 *
69 * @short Checkbox like action.
70 */
71class KToggleAction : public KAction
72{
73 Q_OBJECT
74 Q_PROPERTY( bool checked READ isChecked WRITE setChecked )
75 Q_PROPERTY( QString exclusiveGroup READ exclusiveGroup WRITE setExclusiveGroup )
76public:
77
78 /**
79 * Constructs a toggle action with text and potential keyboard
80 * accelerator but nothing else. Use this only if you really
81 * know what you are doing.
82 *
83 * @param text The text that will be displayed.
84 * @param cut The corresponding keyboard accelerator (shortcut).
85 * @param parent This action's parent.
86 * @param name An internal name for this action.
87 */
88 KToggleAction( const QString& text, const KShortcut& cut = KShortcut(), QObject* parent = 0, const char* name = 0 );
89
90 /**
91 * @param text The text that will be displayed.
92 * @param cut The corresponding keyboard accelerator (shortcut).
93 * @param receiver The SLOT's parent.
94 * @param slot The SLOT to invoke to execute this action.
95 * @param parent This action's parent.
96 * @param name An internal name for this action.
97 */
98 KToggleAction( const QString& text, const KShortcut& cut,
99 const QObject* receiver, const char* slot, QObject* parent, const char* name = 0 );
100
101 /**
102 * @param text The text that will be displayed.
103 * @param pix The icons that go with this action.
104 * @param cut The corresponding keyboard accelerator (shortcut).
105 * @param parent This action's parent.
106 * @param name An internal name for this action.
107 */
108 KToggleAction( const QString& text, const QIconSet& pix, const KShortcut& cut = KShortcut(),
109 QObject* parent = 0, const char* name = 0 );
110
111 /**
112 * @param text The text that will be displayed.
113 * @param pix The dynamically loaded icon that goes with this action.
114 * @param cut The corresponding keyboard accelerator (shortcut).
115 * @param parent This action's parent.
116 * @param name An internal name for this action.
117 */
118 KToggleAction( const QString& text, const QString& pix, const KShortcut& cut = KShortcut(),
119 QObject* parent = 0, const char* name = 0 );
120
121 /**
122 * @param text The text that will be displayed.
123 * @param pix The icons that go with this action.
124 * @param cut The corresponding keyboard accelerator (shortcut).
125 * @param receiver The SLOT's parent.
126 * @param slot The SLOT to invoke to execute this action.
127 * @param parent This action's parent.
128 * @param name An internal name for this action.
129 */
130 KToggleAction( const QString& text, const QIconSet& pix, const KShortcut& cut,
131 const QObject* receiver, const char* slot, QObject* parent, const char* name = 0 );
132
133 /**
134 * @param text The text that will be displayed.
135 * @param pix The dynamically loaded icon that goes with this action.
136 * @param cut The corresponding keyboard accelerator (shortcut).
137 * @param receiver The SLOT's parent.
138 * @param slot The SLOT to invoke to execute this action.
139 * @param parent This action's parent.
140 * @param name An internal name for this action.
141 */
142 KToggleAction( const QString& text, const QString& pix, const KShortcut& cut,
143 const QObject* receiver, const char* slot,
144 QObject* parent, const char* name = 0 );
145
146 /**
147 * @param parent This action's parent.
148 * @param name An internal name for this action.
149 */
150 KToggleAction( QObject* parent = 0, const char* name = 0 );
151
152 /**
153 * Destructor
154 */
155 virtual ~KToggleAction();
156
157 /**
158 * "Plug" or insert this action into a given widget.
159 *
160 * This will typically be a menu or a toolbar. From this point
161 * on, you will never need to directly manipulate the item in the
162 * menu or toolbar. You do all enabling/disabling/manipulation
163 * directly with your KToggleAction object.
164 *
165 * @param widget The GUI element to display this action.
166 * @param index The index of the item.
167 */
168 virtual int plug( QWidget* widget, int index = -1 );
169
170 /**
171 * Returns the actual state of the action.
172 */
173 bool isChecked() const;
174
175 /**
176 * @return which "exclusive group" this action is part of.
177 * @see setExclusiveGroup
178 */
179 QString exclusiveGroup() const;
180
181 /**
182 * Defines which "exclusive group" this action is part of.
183 * In a given exclusive group, only one toggle action can be checked
184 * at a any moment. Checking an action unchecks the other actions
185 * of the group.
186 */
187 virtual void setExclusiveGroup( const QString& name );
188
189public slots:
190 /**
191 * Sets the state of the action.
192 */
193 virtual void setChecked( bool );
194
195protected slots:
196 virtual void slotActivated();
197
198protected:
199 virtual void updateChecked( int id );
200
201signals:
202 void toggled( bool );
203
204protected:
205 virtual void virtual_hook( int id, void* data );
206private:
207 class KToggleActionPrivate;
208 KToggleActionPrivate *d;
209};
210
211/**
212 * An action that operates like a radio button. At any given time
213 * only a single action from the group will be active.
214 */
215class KRadioAction : public KToggleAction
216{
217 Q_OBJECT
218public:
219 /**
220 * Constructs a radio action with text and potential keyboard
221 * accelerator but nothing else. Use this only if you really
222 * know what you are doing.
223 *
224 * @param text The text that will be displayed.
225 * @param cut The corresponding keyboard accelerator (shortcut).
226 * @param parent This action's parent.
227 * @param name An internal name for this action.
228 */
229 KRadioAction( const QString& text, const KShortcut& cut = KShortcut(), QObject* parent = 0, const char* name = 0 );
230
231 /**
232 * @param text The text that will be displayed.
233 * @param cut The corresponding keyboard accelerator (shortcut).
234 * @param receiver The SLOT's parent.
235 * @param slot The SLOT to invoke to execute this action.
236 * @param parent This action's parent.
237 * @param name An internal name for this action.
238 */
239 KRadioAction( const QString& text, const KShortcut& cut,
240 const QObject* receiver, const char* slot, QObject* parent, const char* name = 0 );
241
242 /**
243 * @param text The text that will be displayed.
244 * @param pix The icons that go with this action.
245 * @param cut The corresponding keyboard accelerator (shortcut).
246 * @param parent This action's parent.
247 * @param name An internal name for this action.
248 */
249 KRadioAction( const QString& text, const QIconSet& pix, const KShortcut& cut = KShortcut(),
250 QObject* parent = 0, const char* name = 0 );
251
252 /**
253 * @param text The text that will be displayed.
254 * @param pix The dynamically loaded icon that goes with this action.
255 * @param cut The corresponding keyboard accelerator (shortcut).
256 * @param parent This action's parent.
257 * @param name An internal name for this action.
258 */
259 KRadioAction( const QString& text, const QString& pix, const KShortcut& cut = KShortcut(),
260 QObject* parent = 0, const char* name = 0 );
261
262 /**
263 * @param text The text that will be displayed.
264 * @param pix The icons that go with this action.
265 * @param cut The corresponding keyboard accelerator (shortcut).
266 * @param receiver The SLOT's parent.
267 * @param slot The SLOT to invoke to execute this action.
268 * @param parent This action's parent.
269 * @param name An internal name for this action.
270 */
271 KRadioAction( const QString& text, const QIconSet& pix, const KShortcut& cut,
272 const QObject* receiver, const char* slot, QObject* parent, const char* name = 0 );
273
274 /**
275 * @param text The text that will be displayed.
276 * @param pix The dynamically loaded icon that goes with this action.
277 * @param cut The corresponding keyboard accelerator (shortcut).
278 * @param receiver The SLOT's parent.
279 * @param slot The SLOT to invoke to execute this action.
280 * @param parent This action's parent.
281 * @param name An internal name for this action.
282 */
283 KRadioAction( const QString& text, const QString& pix, const KShortcut& cut,
284 const QObject* receiver, const char* slot,
285 QObject* parent, const char* name = 0 );
286
287 /**
288 * @param parent This action's parent.
289 * @param name An internal name for this action.
290 */
291 KRadioAction( QObject* parent = 0, const char* name = 0 );
292
293protected:
294 virtual void slotActivated();
295
296protected:
297 virtual void virtual_hook( int id, void* data );
298private:
299 class KRadioActionPrivate;
300 KRadioActionPrivate *d;
301};
302
303/**
304 * Action for selecting one of several items.
305 *
306 * This action shows up a submenu with a list of items.
307 * One of them can be checked. If the user clicks on an item
308 * this item will automatically be checked,
309 * the formerly checked item becomes unchecked.
310 * There can be only one item checked at a time.
311 *
312 * @short Action for selecting one of several items
313 */
314class KSelectAction : public KAction
315{
316 Q_OBJECT
317 Q_PROPERTY( int currentItem READ currentItem WRITE setCurrentItem )
318 Q_PROPERTY( QStringList items READ items WRITE setItems )
319 Q_PROPERTY( bool editable READ isEditable WRITE setEditable )
320 Q_PROPERTY( int comboWidth READ comboWidth WRITE setComboWidth )
321 Q_PROPERTY( QString currentText READ currentText )
322 Q_PROPERTY( bool menuAccelsEnabled READ menuAccelsEnabled WRITE setMenuAccelsEnabled )
323public:
324
325 /**
326 * Constructs a select action with text and potential keyboard
327 * accelerator but nothing else. Use this only if you really
328 * know what you are doing.
329 *
330 * @param text The text that will be displayed.
331 * @param cut The corresponding keyboard accelerator (shortcut).
332 * @param parent This action's parent.
333 * @param name An internal name for this action.
334 */
335 KSelectAction( const QString& text, const KShortcut& cut = KShortcut(), QObject* parent = 0, const char* name = 0 );
336
337 /**
338 * @param text The text that will be displayed.
339 * @param cut The corresponding keyboard accelerator (shortcut).
340 * @param receiver The SLOT's parent.
341 * @param slot The SLOT to invoke to execute this action.
342 * @param parent This action's parent.
343 * @param name An internal name for this action.
344 */
345 KSelectAction( const QString& text, const KShortcut& cut,
346 const QObject* receiver, const char* slot, QObject* parent, const char* name = 0 );
347
348 /**
349 * @param text The text that will be displayed.
350 * @param pix The icons that go with this action.
351 * @param cut The corresponding keyboard accelerator (shortcut).
352 * @param parent This action's parent.
353 * @param name An internal name for this action.
354 */
355 KSelectAction( const QString& text, const QIconSet& pix, const KShortcut& cut = KShortcut(),
356 QObject* parent = 0, const char* name = 0 );
357
358 /**
359 * @param text The text that will be displayed.
360 * @param pix The dynamically loaded icon that goes with this action.
361 * @param cut The corresponding keyboard accelerator (shortcut).
362 * @param parent This action's parent.
363 * @param name An internal name for this action.
364 */
365 KSelectAction( const QString& text, const QString& pix, const KShortcut& cut = KShortcut(),
366 QObject* parent = 0, const char* name = 0 );
367
368 /**
369 * @param text The text that will be displayed.
370 * @param pix The icons that go with this action.
371 * @param cut The corresponding keyboard accelerator (shortcut).
372 * @param receiver The SLOT's parent.
373 * @param slot The SLOT to invoke to execute this action.
374 * @param parent This action's parent.
375 * @param name An internal name for this action.
376 */
377 KSelectAction( const QString& text, const QIconSet& pix, const KShortcut& cut,
378 const QObject* receiver, const char* slot, QObject* parent, const char* name = 0 );
379
380 /**
381 * @param text The text that will be displayed.
382 * @param pix The dynamically loaded icon that goes with this action.
383 * @param cut The corresponding keyboard accelerator (shortcut).
384 * @param receiver The SLOT's parent.
385 * @param slot The SLOT to invoke to execute this action.
386 * @param parent This action's parent.
387 * @param name An internal name for this action.
388 */
389 KSelectAction( const QString& text, const QString& pix, const KShortcut& cut,
390 const QObject* receiver, const char* slot,
391 QObject* parent, const char* name = 0 );
392
393 /**
394 * @param parent This action's parent.
395 * @param name An internal name for this action.
396 */
397 KSelectAction( QObject* parent = 0, const char* name = 0 );
398
399 /**
400 * Destructor
401 */
402 virtual ~KSelectAction();
403
404 /**
405 * "Plug" or insert this action into a given widget.
406 *
407 * This will typically be a menu or a toolbar.
408 * From this point on, you will never need to directly
409 * manipulate the item in the menu or toolbar.
410 * You do all enabling/disabling/manipulation directly with your KSelectAction object.
411 *
412 * @param widget The GUI element to display this action.
413 * @param index The index of the item.
414 */
415 virtual int plug( QWidget* widget, int index = -1 );
416
417 /**
418 * When this action is plugged into a toolbar, it creates a combobox.
419 * @return true if the combo editable.
420 */
421 virtual bool isEditable() const;
422
423 /**
424 * @return the items that can be selected with this action.
425 * Use setItems to set them.
426 */
427 virtual QStringList items() const;
428
429 virtual void changeItem( int index, const QString& text );
430
431 virtual QString currentText() const;
432
433 virtual int currentItem() const;
434
435 /**
436 * When this action is plugged into a toolbar, it creates a combobox.
437 * This returns the maximum width set by setComboWidth
438 */
439 virtual int comboWidth() const;
440
441 QPopupMenu* popupMenu() const;
442
443 /**
444 * Deprecated. See @ref setMenuAccelsEnabled .
445 * @since 3.1
446 */
447 void setRemoveAmpersandsInCombo( bool b );
448 /// @since 3.1
449 bool removeAmpersandsInCombo() const;
450
451 /**
452 * Sets whether any occurence of the ampersand character ( &amp; ) in items
453 * should be interpreted as keyboard accelerator for items displayed in a
454 * menu or not.
455 * @since 3.1
456 */
457 void setMenuAccelsEnabled( bool b );
458 /// @since 3.1
459 bool menuAccelsEnabled() const;
460
461public slots:
462 /**
463 * Sets the currently checked item.
464 *
465 * @param index Index of the item (remember the first item is zero).
466 */
467 virtual void setCurrentItem( int index );
468
469 /**
470 * Sets the items to be displayed in this action
471 * You need to call this.
472 */
473 virtual void setItems( const QStringList &lst );
474
475 /**
476 * Clears up all the items in this action
477 */
478 virtual void clear();
479
480 /**
481 * When this action is plugged into a toolbar, it creates a combobox.
482 * This makes the combo editable or read-only.
483 */
484 virtual void setEditable( bool );
485
486 /**
487 * When this action is plugged into a toolbar, it creates a combobox.
488 * This gives a _maximum_ size to the combobox.
489 * The minimum size is automatically given by the contents (the items).
490 */
491 virtual void setComboWidth( int width );
492
493protected:
494 virtual void changeItem( int id, int index, const QString& text );
495
496 /**
497 * Depending on the menuAccelsEnabled property this method will return the
498 * actions items in a way for inclusion in a combobox with the ampersand
499 * character removed from all items or not.
500 * @since 3.1
501 */
502 QStringList comboItems() const;
503
504protected slots:
505 virtual void slotActivated( int id );
506 virtual void slotActivated( const QString &text );
507 virtual void slotActivated();
508
509signals:
510 void activated( int index );
511 void activated( const QString& text );
512
513protected:
514 virtual void updateCurrentItem( int id );
515
516 virtual void updateComboWidth( int id );
517
518 virtual void updateItems( int id );
519
520 virtual void updateClear( int id );
521
522protected:
523 virtual void virtual_hook( int id, void* data );
524private:
525 void setupMenu() const;
526 class KSelectActionPrivate;
527 KSelectActionPrivate *d;
528
529};
530
531/// Remove this class in KDE-4.0. It doesn't add _anything_ to KSelectAction
532/**
533 * @deprecated Use KSelectAction instead.
534 */
535class KListAction : public KSelectAction
536{
537 Q_OBJECT
538public:
539 /**
540 * Constructs a list action with text and potential keyboard
541 * accelerator but nothing else. Use this only if you really
542 * know what you are doing.
543 *
544 * @param text The text that will be displayed.
545 * @param cut The corresponding keyboard accelerator (shortcut).
546 * @param parent This action's parent.
547 * @param name An internal name for this action.
548 */
549 KListAction( const QString& text, const KShortcut& cut = KShortcut(), QObject* parent = 0,
550 const char* name = 0 );
551
552 /**
553 * @param text The text that will be displayed.
554 * @param cut The corresponding keyboard accelerator (shortcut).
555 * @param receiver The SLOT's parent.
556 * @param slot The SLOT to invoke to execute this action.
557 * @param parent This action's parent.
558 * @param name An internal name for this action.
559 */
560 KListAction( const QString& text, const KShortcut& cut, const QObject* receiver,
561 const char* slot, QObject* parent, const char* name = 0 );
562
563 /**
564 * @param text The text that will be displayed.
565 * @param pix The icons that go with this action.
566 * @param cut The corresponding keyboard accelerator (shortcut).
567 * @param parent This action's parent.
568 * @param name An internal name for this action.
569 */
570 KListAction( const QString& text, const QIconSet& pix, const KShortcut& cut = KShortcut(),
571 QObject* parent = 0, const char* name = 0 );
572
573 /**
574 * @param text The text that will be displayed.
575 * @param pix The dynamically loaded icon that goes with this action.
576 * @param cut The corresponding keyboard accelerator (shortcut).
577 * @param parent This action's parent.
578 * @param name An internal name for this action.
579 */
580 KListAction( const QString& text, const QString& pix, const KShortcut& cut = KShortcut(),
581 QObject* parent = 0, const char* name = 0 );
582
583 /**
584 * @param text The text that will be displayed.
585 * @param pix The icons that go with this action.
586 * @param cut The corresponding keyboard accelerator (shortcut).
587 * @param receiver The SLOT's parent.
588 * @param slot The SLOT to invoke to execute this action.
589 * @param parent This action's parent.
590 * @param name An internal name for this action.
591 */
592 KListAction( const QString& text, const QIconSet& pix, const KShortcut& cut,
593 const QObject* receiver, const char* slot, QObject* parent,
594 const char* name = 0 );
595
596 /**
597 * @param text The text that will be displayed.
598 * @param pix The dynamically loaded icon that goes with this action.
599 * @param cut The corresponding keyboard accelerator (shortcut).
600 * @param receiver The SLOT's parent.
601 * @param slot The SLOT to invoke to execute this action.
602 * @param parent This action's parent.
603 * @param name An internal name for this action.
604 */
605 KListAction( const QString& text, const QString& pix, const KShortcut& cut,
606 const QObject* receiver, const char* slot, QObject* parent,
607 const char* name = 0 );
608
609 /**
610 * @param parent This action's parent.
611 * @param name An internal name for this action.
612 */
613 KListAction( QObject* parent = 0, const char* name = 0 );
614
615 /**
616 * Destructor
617 */
618 virtual ~KListAction();
619
620
621 virtual QString currentText() const;
622 virtual int currentItem() const;
623
624
625public slots:
626 /**
627 * Sets the currently checked item.
628 *
629 * @param index Index of the item (remember the first item is zero).
630 */
631 virtual void setCurrentItem( int index );
632
633protected:
634 virtual void virtual_hook( int id, void* data );
635private:
636 class KListActionPrivate;
637 KListActionPrivate *d;
638};
639
640/**
641 * This class is an action to handle a recent files submenu.
642 * The best way to create the action is to use KStdAction::openRecent.
643 * Then you simply need to call @ref loadEntries on startup, @ref saveEntries
644 * on shutdown, @ref addURL when your application loads/saves a file.
645 *
646 * @author Michael Koch
647 * @short Recent files action
648 */
649class KRecentFilesAction : public KListAction // TODO public KSelectAction
650{
651 Q_OBJECT
652 Q_PROPERTY( uint maxItems READ maxItems WRITE setMaxItems )
653public:
654 /**
655 * @param text The text that will be displayed.
656 * @param cut The corresponding keyboard accelerator (shortcut).
657 * @param parent This action's parent.
658 * @param name An internal name for this action.
659 * @param maxItems The maximum number of files to display
660 */
661 KRecentFilesAction( const QString& text, const KShortcut& cut,
662 QObject* parent, const char* name = 0,
663 uint maxItems = 10 );
664
665 /**
666 * @param text The text that will be displayed.
667 * @param cut The corresponding keyboard accelerator (shortcut).
668 * @param receiver The SLOT's parent.
669 * @param slot The SLOT to invoke when a URL is selected.
670 * Its signature is of the form slotURLSelected( const KURL & ).
671 * @param parent This action's parent.
672 * @param name An internal name for this action.
673 * @param maxItems The maximum number of files to display
674 */
675 KRecentFilesAction( const QString& text, const KShortcut& cut,
676 const QObject* receiver, const char* slot,
677 QObject* parent, const char* name = 0,
678 uint maxItems = 10 );
679
680 /**
681 * @param text The text that will be displayed.
682 * @param pix The icons that go with this action.
683 * @param cut The corresponding keyboard accelerator (shortcut).
684 * @param parent This action's parent.
685 * @param name An internal name for this action.
686 * @param maxItems The maximum number of files to display
687 */
688 KRecentFilesAction( const QString& text, const QIconSet& pix, const KShortcut& cut,
689 QObject* parent, const char* name = 0,
690 uint maxItems = 10 );
691
692 /**
693 * @param text The text that will be displayed.
694 * @param pix The dynamically loaded icon that goes with this action.
695 * @param cut The corresponding keyboard accelerator (shortcut).
696 * @param parent This action's parent.
697 * @param name An internal name for this action.
698 * @param maxItems The maximum number of files to display
699 */
700 KRecentFilesAction( const QString& text, const QString& pix, const KShortcut& cut,
701 QObject* parent, const char* name = 0,
702 uint maxItems = 10 );
703
704 /**
705 * @param text The text that will be displayed.
706 * @param pix The icons that go with this action.
707 * @param cut The corresponding keyboard accelerator (shortcut).
708 * @param receiver The SLOT's parent.
709 * @param slot The SLOT to invoke when a URL is selected.
710 * Its signature is of the form slotURLSelected( const KURL & ).
711 * @param parent This action's parent.
712 * @param name An internal name for this action.
713 * @param maxItems The maximum number of files to display
714 */
715 KRecentFilesAction( const QString& text, const QIconSet& pix, const KShortcut& cut,
716 const QObject* receiver, const char* slot,
717 QObject* parent, const char* name = 0,
718 uint maxItems = 10 );
719
720 /**
721 * @param text The text that will be displayed.
722 * @param pix The dynamically loaded icon that goes with this action.
723 * @param cut The corresponding keyboard accelerator (shortcut).
724 * @param receiver The SLOT's parent.
725 * @param slot The SLOT to invoke when a URL is selected.
726 * Its signature is of the form slotURLSelected( const KURL & ).
727 * @param parent This action's parent.
728 * @param name An internal name for this action.
729 * @param maxItems The maximum number of files to display
730 */
731 KRecentFilesAction( const QString& text, const QString& pix, const KShortcut& cut,
732 const QObject* receiver, const char* slot,
733 QObject* parent, const char* name = 0,
734 uint maxItems = 10 );
735
736 /**
737 * @param parent This action's parent.
738 * @param name An internal name for this action.
739 * @param maxItems The maximum number of files to display
740 */
741 KRecentFilesAction( QObject* parent = 0, const char* name = 0,
742 uint maxItems = 10 );
743
744 /**
745 * Destructor.
746 */
747 virtual ~KRecentFilesAction();
748
749 /**
750 * Returns the maximum of items in the recent files list.
751 */
752 uint maxItems() const;
753
754public slots:
755 /**
756 * Sets the maximum of items in the recent files list.
757 * The default for this value is 10 set in the constructor.
758 *
759 * If this value is lesser than the number of items currently
760 * in the recent files list the last items are deleted until
761 * the number of items are equal to the new maximum.
762 */
763 void setMaxItems( uint maxItems );
764
765 /**
766 * Loads the recent files entries from a given KConfig object.
767 * You can provide the name of the group used to load the entries.
768 * If the groupname is empty, entries are load from a group called 'RecentFiles'
769 *
770 * This method does not effect the active group of KConfig.
771 */
772 void loadEntries( KConfig* config, QString groupname=QString::null );
773
774 /**
775 * Saves the current recent files entries to a given KConfig object.
776 * You can provide the name of the group used to load the entries.
777 * If the groupname is empty, entries are saved to a group called 'RecentFiles'
778 *
779 * This method does not effect the active group of KConfig.
780 */
781 void saveEntries( KConfig* config, QString groupname=QString::null );
782
783public slots:
784 /**
785 * Add URL to recent files list.
786 *
787 * @param url The URL of the file
788 */
789 void addURL( const KURL& url );
790
791 /**
792 * Remove an URL from the recent files list.
793 *
794 * @param url The URL of the file
795 */
796 void removeURL( const KURL& url );
797
798 /**
799 * Removes all entries from the recent files list.
800 */
801 void clearURLList();
802
803signals:
804
805 /**
806 * This signal gets emited when the user selects an URL.
807 *
808 * @param url The URL thats the user selected.
809 */
810 void urlSelected( const KURL& url );
811
812protected slots:
813 /**
814 *
815 */
816 void itemSelected( const QString& string );
817
818protected:
819 virtual void virtual_hook( int id, void* data );
820private:
821 void init();
822
823 class KRecentFilesActionPrivate;
824 KRecentFilesActionPrivate *d;
825};
826
827class KFontAction : public KSelectAction
828{
829 Q_OBJECT
830 Q_PROPERTY( QString font READ font WRITE setFont )
831public:
832 KFontAction( const QString& text, const KShortcut& cut = KShortcut(), QObject* parent = 0,
833 const char* name = 0 );
834 KFontAction( const QString& text, const KShortcut& cut,
835 const QObject* receiver, const char* slot, QObject* parent,
836 const char* name = 0 );
837 KFontAction( const QString& text, const QIconSet& pix, const KShortcut& cut = KShortcut(),
838 QObject* parent = 0, const char* name = 0 );
839 KFontAction( const QString& text, const QString& pix, const KShortcut& cut = KShortcut(),
840 QObject* parent = 0, const char* name = 0 );
841 KFontAction( const QString& text, const QIconSet& pix, const KShortcut& cut,
842 const QObject* receiver, const char* slot, QObject* parent,
843 const char* name = 0 );
844 KFontAction( const QString& text, const QString& pix, const KShortcut& cut,
845 const QObject* receiver, const char* slot, QObject* parent,
846 const char* name = 0 );
847
848 KFontAction( QObject* parent = 0, const char* name = 0 );
849 ~KFontAction();
850
851 QString font() const {
852 return currentText();
853 }
854
855 int plug( QWidget*, int index = -1 );
856
857public slots:
858 void setFont( const QString &family );
859
860protected:
861 virtual void virtual_hook( int id, void* data );
862private:
863 class KFontActionPrivate;
864 KFontActionPrivate *d;
865};
866
867class KFontSizeAction : public KSelectAction
868{
869 Q_OBJECT
870 Q_PROPERTY( int fontSize READ fontSize WRITE setFontSize )
871public:
872 KFontSizeAction( const QString& text, const KShortcut& cut = KShortcut(), QObject* parent = 0,
873 const char* name = 0 );
874 KFontSizeAction( const QString& text, const KShortcut& cut, const QObject* receiver,
875 const char* slot, QObject* parent, const char* name = 0 );
876 KFontSizeAction( const QString& text, const QIconSet& pix, const KShortcut& cut = KShortcut(),
877 QObject* parent = 0, const char* name = 0 );
878 KFontSizeAction( const QString& text, const QString& pix, const KShortcut& cut = KShortcut(),
879 QObject* parent = 0, const char* name = 0 );
880 KFontSizeAction( const QString& text, const QIconSet& pix, const KShortcut& cut,
881 const QObject* receiver, const char* slot,
882 QObject* parent, const char* name = 0 );
883 KFontSizeAction( const QString& text, const QString& pix, const KShortcut& cut,
884 const QObject* receiver, const char* slot,
885 QObject* parent, const char* name = 0 );
886 KFontSizeAction( QObject* parent = 0, const char* name = 0 );
887
888 virtual ~KFontSizeAction();
889
890 virtual int fontSize() const;
891
892public slots:
893 virtual void setFontSize( int size );
894
895protected slots:
896 virtual void slotActivated( int );
897 virtual void slotActivated( const QString& );
898 virtual void slotActivated() { KAction::slotActivated(); }
899
900signals:
901 void fontSizeChanged( int );
902
903private:
904 void init();
905
906
907protected:
908 virtual void virtual_hook( int id, void* data );
909private:
910 class KFontSizeActionPrivate;
911 KFontSizeActionPrivate *d;
912};
913
914
915/**
916 * A KActionMenu is an action that holds a sub-menu of other actions.
917 * insert() and remove() allow to insert and remove actions into this action-menu.
918 * Plugged in a popupmenu, it will create a submenu.
919 * Plugged in a toolbar, it will create a button with a popup menu.
920 *
921 * This is the action used by the XMLGUI since it holds other actions.
922 * If you want a submenu for selecting one tool among many (without icons), see KSelectAction.
923 * See also setDelayed about the main action.
924 */
925class KActionMenu : public KAction
926{
927 Q_OBJECT
928 Q_PROPERTY( bool delayed READ delayed WRITE setDelayed )
929 Q_PROPERTY( bool stickyMenu READ stickyMenu WRITE setStickyMenu )
930
931public:
932 KActionMenu( const QString& text, QObject* parent = 0,
933 const char* name = 0 );
934 KActionMenu( const QString& text, const QIconSet& icon,
935 QObject* parent = 0, const char* name = 0 );
936 KActionMenu( const QString& text, const QString& icon,
937 QObject* parent = 0, const char* name = 0 );
938 KActionMenu( QObject* parent = 0, const char* name = 0 );
939 virtual ~KActionMenu();
940
941 virtual void insert( KAction*, int index = -1 );
942 virtual void remove( KAction* );
943
944//US KPopupMenu* popupMenu() const;
945 QPopupMenu* popupMenu() const;
946 void popup( const QPoint& global );
947
948 /**
949 * Returns true if this action creates a delayed popup menu
950 * when plugged in a KToolbar.
951 */
952 bool delayed() const;
953 /**
954 * If set to true, this action will create a delayed popup menu
955 * when plugged in a KToolbar. Otherwise it creates a normal popup.
956 * Default: delayed
957 *
958 * Remember that if the "main" action (the toolbar button itself)
959 * cannot be clicked, then you should call setDelayed(false).
960 *
961 * On the opposite, if the main action can be clicked, it can only happen
962 * in a toolbar: in a menu, the parent of a submenu can't be activated.
963 * To get a "normal" menu item when plugged a menu (and no submenu)
964 * use KToolBarPopupAction.
965 */
966 void setDelayed(bool _delayed);
967
968 /**
969 * Returns true if this action creates a sticky popup menu.
970 * See @ref setStickyMenu.
971 */
972 bool stickyMenu() const;
973 /**
974 * If set to true, this action will create a sticky popup menu
975 * when plugged in a KToolbar.
976 * "Sticky", means it's visible until a selection is made or the mouse is
977 * clicked elsewhere. This feature allows you to make a selection without
978 * having to press and hold down the mouse while making a selection.
979 * Default: sticky.
980 */
981 void setStickyMenu(bool sticky);
982
983 virtual int plug( QWidget* widget, int index = -1 );
984
985protected:
986 virtual void virtual_hook( int id, void* data );
987private:
988 class KActionMenuPrivate;
989 KActionMenuPrivate *d;
990};
991
992/**
993 * This action is a normal action everywhere, except in a toolbar
994 * where it also has a popupmenu (optionnally delayed). This action is designed
995 * for history actions (back/forward, undo/redo) and for any other action
996 * that has more detail in a toolbar than in a menu (e.g. tool chooser
997 * with "Other" leading to a dialog...).
998 */
999class KToolBarPopupAction : public KAction
1000{
1001 Q_OBJECT
1002 Q_PROPERTY( bool delayed READ delayed WRITE setDelayed )
1003 Q_PROPERTY( bool stickyMenu READ stickyMenu WRITE setStickyMenu )
1004
1005public:
1006 //Not all constructors - because we need an icon, since this action only makes
1007 // sense when being plugged at least in a toolbar.
1008 /**
1009 * Create a KToolBarPopupAction, with a text, an icon, an optionnal accelerator,
1010 * parent and name.
1011 *
1012 * @param text The text that will be displayed.
1013 * @param icon The icon to display.
1014 * @param cut The corresponding keyboard accelerator (shortcut).
1015 * @param parent This action's parent.
1016 * @param name An internal name for this action.
1017 */
1018 KToolBarPopupAction( const QString& text, const QString& icon, const KShortcut& cut = KShortcut(),
1019 QObject* parent = 0, const char* name = 0 );
1020
1021 /**
1022 * Create a KToolBarPopupAction, with a text, an icon, an accelerator,
1023 * a slot connected to the action, parent and name.
1024 *
1025 * If you do not want or have a keyboard accelerator, set the
1026 * @p cut param to 0.
1027 *
1028 * @param text The text that will be displayed.
1029 * @param icon The icon to display.
1030 * @param cut The corresponding keyboard accelerator (shortcut).
1031 * @param receiver The SLOT's owner.
1032 * @param slot The SLOT to invoke to execute this action.
1033 * @param parent This action's parent.
1034 * @param name An internal name for this action.
1035 */
1036 KToolBarPopupAction( const QString& text, const QString& icon, const KShortcut& cut,
1037 const QObject* receiver, const char* slot,
1038 QObject* parent = 0, const char* name = 0 );
1039
1040 /**
1041 * Create a KToolBarPopupAction, with a KGuiItem, an accelerator,
1042 * a slot connected to the action, parent and name. The text and the
1043 * icon are taken from the KGuiItem.
1044 *
1045 * If you do not want or have a keyboard accelerator, set the
1046 * @p cut param to 0.
1047 *
1048 * @param item The text and icon that will be displayed.
1049 * @param cut The corresponding keyboard accelerator (shortcut).
1050 * @param receiver The SLOT's owner.
1051 * @param slot The SLOT to invoke to execute this action.
1052 * @param parent This action's parent.
1053 * @param name An internal name for this action.
1054 */
1055
1056 KToolBarPopupAction( const KGuiItem& item, const KShortcut& cut,
1057 const QObject* receiver, const char* slot,
1058 KActionCollection* parent, const char* name );
1059
1060 virtual ~KToolBarPopupAction();
1061
1062 virtual int plug( QWidget *widget, int index = -1 );
1063
1064 /**
1065 * The popup menu that is shown when clicking (some time) on the toolbar
1066 * button. You may want to plug items into it on creation, or connect to
1067 * aboutToShow for a more dynamic menu.
1068 */
1069//US KPopupMenu *popupMenu() const;
1070 QPopupMenu *popupMenu() const;
1071
1072 /**
1073 * Returns true if this action creates a delayed popup menu
1074 * when plugged in a KToolbar.
1075 */
1076 bool delayed() const;
1077 /**
1078 * If set to true, this action will create a delayed popup menu
1079 * when plugged in a KToolbar. Otherwise it creates a normal popup.
1080 * Default: delayed.
1081 */
1082 void setDelayed(bool delayed);
1083 /**
1084 * Returns true if this action creates a sticky popup menu.
1085 * See @ref setStickyMenu.
1086 */
1087 bool stickyMenu() const;
1088 /**
1089 * If set to true, this action will create a sticky popup menu
1090 * when plugged in a KToolbar.
1091 * "Sticky", means it's visible until a selection is made or the mouse is
1092 * clicked elsewhere. This feature allows you to make a selection without
1093 * having to press and hold down the mouse while making a selection.
1094 * Only available if delayed() is true.
1095 * Default: sticky.
1096 */
1097 void setStickyMenu(bool sticky);
1098
1099private:
1100//US KPopupMenu *m_popup;
1101 QPopupMenu *m_popup;
1102 bool m_delayed:1;
1103 bool m_stickyMenu:1;
1104protected:
1105 virtual void virtual_hook( int id, void* data );
1106private:
1107 class KToolBarPopupActionPrivate;
1108 KToolBarPopupActionPrivate *d;
1109};
1110
1111/**
1112 * An action that takes care of everything associated with
1113 * showing or hiding a toolbar by a menu action. It will
1114 * show or hide the toolbar with the given name when
1115 * activated, and check or uncheck itself if the toolbar
1116 * is manually shown or hidden.
1117 *
1118 * If you need to perfom some additional action when the
1119 * toolbar is shown or hidden, connect to the toggled(bool)
1120 * signal. It will be emitted after the toolbar's
1121 * visibility has changed, whenever it changes.
1122 * @since 3.1
1123 */
1124class KToggleToolBarAction : public KToggleAction
1125{
1126 Q_OBJECT
1127public:
1128 /**
1129 * Create a KToggleToolbarAction that manages the toolbar
1130 * named toolBarName. This can be either the name of a
1131 * toolbar in an xml ui file, or a toolbar programmatically
1132 * created with that name.
1133 */
1134 KToggleToolBarAction( const char* toolBarName, const QString& text,
1135 KActionCollection* parent, const char* name );
1136 KToggleToolBarAction( KToolBar *toolBar, const QString &text,
1137 KActionCollection *parent, const char *name );
1138 virtual ~KToggleToolBarAction();
1139
1140 virtual int plug( QWidget*, int index = -1 );
1141
1142 KToolBar *toolBar() {
1143 return m_toolBar;
1144 }
1145
1146public slots:
1147 virtual void setChecked( bool );
1148
1149private:
1150 QCString m_toolBarName;
1151 QGuardedPtr<KToolBar> m_toolBar;
1152protected:
1153 virtual void virtual_hook( int id, void* data );
1154private:
1155 class KToggleToolBarActionPrivate;
1156 KToggleToolBarActionPrivate *d;
1157};
1158
1159/**
1160 * An action that automatically embeds a widget into a
1161 * toolbar.
1162 */
1163class KWidgetAction : public KAction
1164{
1165 Q_OBJECT
1166public:
1167 /**
1168 * Create an action that will embed widget into a toolbar
1169 * when plugged. This action may only be plugged into
1170 * a toolbar.
1171 */
1172 KWidgetAction( QWidget* widget, const QString& text,
1173 const KShortcut& cut,
1174 const QObject* receiver, const char* slot,
1175 KActionCollection* parent, const char* name );
1176 virtual ~KWidgetAction();
1177
1178 /**
1179 * Returns the widget associated with this action.
1180 */
1181 QWidget* widget() { return m_widget; }
1182
1183 void setAutoSized( bool );
1184
1185 /**
1186 * Plug the action. The widget passed to the constructor
1187 * will be reparented to w, which must inherit KToolBar.
1188 */
1189 virtual int plug( QWidget* w, int index = -1 );
1190 /**
1191 * Unplug the action. Ensures that the action is not
1192 * destroyed. It will be hidden and reparented to 0L instead.
1193 */
1194 virtual void unplug( QWidget *w );
1195protected slots:
1196 void slotToolbarDestroyed();
1197private:
1198 QGuardedPtr<QWidget> m_widget;
1199 bool m_autoSized;
1200protected:
1201 virtual void virtual_hook( int id, void* data );
1202private:
1203 class KWidgetActionPrivate;
1204 KWidgetActionPrivate *d;
1205};
1206
1207class KActionSeparator : public KAction
1208{
1209 Q_OBJECT
1210public:
1211 KActionSeparator( QObject* parent = 0, const char* name = 0 );
1212 virtual ~KActionSeparator();
1213
1214 virtual int plug( QWidget*, int index = -1 );
1215
1216protected:
1217 virtual void virtual_hook( int id, void* data );
1218private:
1219 class KActionSeparatorPrivate;
1220 KActionSeparatorPrivate *d;
1221};
1222
1223#endif
diff --git a/microkde/kdeui/kactioncollection.cpp b/microkde/kdeui/kactioncollection.cpp
new file mode 100644
index 0000000..b819e76
--- a/dev/null
+++ b/microkde/kdeui/kactioncollection.cpp
@@ -0,0 +1,839 @@
1/* This file is part of the KDE libraries
2 Copyright (C) 1999 Reginald Stadlbauer <reggie@kde.org>
3 (C) 1999 Simon Hausmann <hausmann@kde.org>
4 (C) 2000 Nicolas Hadacek <haadcek@kde.org>
5 (C) 2000 Kurt Granroth <granroth@kde.org>
6 (C) 2000 Michael Koch <koch@kde.org>
7 (C) 2001 Holger Freyther <freyther@kde.org>
8 (C) 2002 Ellis Whitehead <ellis@kde.org>
9 (C) 2002 Joseph Wenninger <jowenn@kde.org>
10
11 This library is free software; you can redistribute it and/or
12 modify it under the terms of the GNU Library General Public
13 License version 2 as published by the Free Software Foundation.
14
15 This library is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 Library General Public License for more details.
19
20 You should have received a copy of the GNU Library General Public License
21 along with this library; see the file COPYING.LIB. If not, write to
22 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23 Boston, MA 02111-1307, USA.
24*/
25
26#include "kactioncollection.h"
27//US#include "kactionshortcutlist.h"
28
29#include <qptrdict.h>
30//US#include <qvariant.h>
31
32//US#include <kaccel.h>
33//US#include <kaccelbase.h>
34//US#include <kapplication.h>
35#include <kdebug.h>
36//US#include <kxmlguifactory.h>
37
38//US I included the following files
39#include <qasciidict.h>
40#include <qptrlist.h>
41#include "kaction.h"
42#include <kglobal.h>
43#include <qobject.h>
44#include <qwidget.h>
45
46class KActionCollection::KActionCollectionPrivate
47{
48public:
49 KActionCollectionPrivate()
50 {
51//US m_instance = 0;
52 //m_bOneKAccelOnly = false;
53 //m_iWidgetCurrent = 0;
54 m_bAutoConnectShortcuts = true;
55 m_widget = 0;
56 m_kaccel = m_builderKAccel = 0;
57 m_dctHighlightContainers.setAutoDelete( true );
58 m_highlight = false;
59 m_currentHighlightAction = 0;
60 m_statusCleared = true;
61 }
62
63//US KInstance *m_instance;
64//US QString m_sXMLFile;
65 bool m_bAutoConnectShortcuts;
66 //bool m_bOneKAccelOnly;
67 //int m_iWidgetCurrent;
68 //QValueList<QWidget*> m_widgetList;
69 //QValueList<KAccel*> m_kaccelList;
70 QValueList<KActionCollection*> m_docList;
71 QWidget *m_widget;
72 KAccel *m_kaccel;
73 KAccel *m_builderKAccel;
74
75 QAsciiDict<KAction> m_actionDict;
76 QPtrDict< QPtrList<KAction> > m_dctHighlightContainers;
77 bool m_highlight;
78 KAction *m_currentHighlightAction;
79 bool m_statusCleared;
80};
81
82KActionCollection::KActionCollection( QWidget *parent, const char *name /*US,
83 KInstance *instance */)
84 : QObject( (QObject*)parent, name )
85{
86 kdDebug(129) << "KActionCollection::KActionCollection( " << parent << ", " << name << " ): this = " << this << endl; // ellis
87 d = new KActionCollectionPrivate;
88 if( parent )
89 setWidget( parent );
90 //d->m_bOneKAccelOnly = (d->m_kaccelList.count() > 0);
91//US setInstance( instance );
92}
93
94
95KActionCollection::KActionCollection( QWidget *watch, QObject* parent, const char *name /*US,
96 KInstance *instance */)
97 : QObject( parent, name )
98{
99 kdDebug(129) << "KActionCollection::KActionCollection( " << watch << ", " << parent << ", " << name << " ): this = " << this << endl; //ellis
100 d = new KActionCollectionPrivate;
101 if( watch )
102 setWidget( watch );
103 //d->m_bOneKAccelOnly = (d->m_kaccelList.count() > 0);
104//US setInstance( instance );
105}
106
107// KDE 4: remove
108KActionCollection::KActionCollection( QObject *parent, const char *name /*US,
109 KInstance *instance */)
110 : QObject( parent, name )
111{
112 kdWarning(129) << "KActionCollection::KActionCollection( QObject *parent, const char *name, KInstance *instance )" << endl; //ellis
113//US kdBacktrace not available
114//US kdDebug(129) << kdBacktrace() << endl;
115 d = new KActionCollectionPrivate;
116//US QWidget* w = dynamic_cast<QWidget*>( parent );
117 QWidget* w = (QWidget*)( parent );
118 if( w )
119 setWidget( w );
120 //d->m_bOneKAccelOnly = (d->m_kaccelList.count() > 0);
121//US setInstance( instance );
122}
123
124KActionCollection::KActionCollection( const KActionCollection &copy )
125 : QObject()
126{
127 kdWarning(129) << "KActionCollection::KActionCollection( const KActionCollection & ): function is severely deprecated." << endl;
128 d = new KActionCollectionPrivate;
129 *this = copy;
130}
131// KDE 4: remove end
132
133KActionCollection::~KActionCollection()
134{
135 kdDebug(129) << "KActionCollection::~KActionCollection(): this = " << this << endl;
136 for ( QAsciiDictIterator<KAction> it( d->m_actionDict ); it.current(); ++it ) {
137 KAction* pAction = it.current();
138 if ( pAction->m_parentCollection == this )
139 pAction->m_parentCollection = 0L;
140 }
141
142//US delete d->m_kaccel;
143//US delete d->m_builderKAccel;
144 delete d; d = 0;
145}
146
147void KActionCollection::setWidget( QWidget* w )
148{
149 //if ( d->m_actionDict.count() > 0 ) {
150 // kdError(129) << "KActionCollection::setWidget(): must be called before any actions are added to collection!" << endl;
151 // kdDebug(129) << kdBacktrace() << endl;
152 //}
153 //else
154 if ( !d->m_widget ) {
155 d->m_widget = w;
156 qDebug("KActionCollection::setWidget: warning: KAccel is never used in microkde");
157//US d->m_kaccel = new KAccel( w, this, "KActionCollection-KAccel" );
158 }
159 else if ( d->m_widget != w )
160 kdWarning(129) << "KActionCollection::setWidget(): tried to change widget from " << d->m_widget << " to " << w << endl;
161}
162
163void KActionCollection::setAutoConnectShortcuts( bool b )
164{
165 d->m_bAutoConnectShortcuts = b;
166}
167
168bool KActionCollection::isAutoConnectShortcuts()
169{
170 return d->m_bAutoConnectShortcuts;
171}
172
173bool KActionCollection::addDocCollection( KActionCollection* pDoc )
174{
175 d->m_docList.append( pDoc );
176 return true;
177}
178
179void KActionCollection::beginXMLPlug( QWidget *widget )
180{
181 qDebug("KActionCollection::beginXMLPlug has to be fixed");
182/*US
183 kdDebug(129) << "KActionCollection::beginXMLPlug( buildWidget = " << widget << " ): this = " << this << " d->m_builderKAccel = " << d->m_builderKAccel << endl;
184
185 if( widget && !d->m_builderKAccel ) {
186 d->m_builderKAccel = new KAccel( widget, this, "KActionCollection-BuilderKAccel" );
187 }
188*/
189}
190
191void KActionCollection::endXMLPlug()
192{
193 kdDebug(129) << "KActionCollection::endXMLPlug(): this = " << this << endl;
194 //s_kaccelXML = 0;
195}
196
197void KActionCollection::prepareXMLUnplug()
198{
199 qDebug("KActionCollection::prepareXMLUnplug has to be fixed");
200/*US
201 kdDebug(129) << "KActionCollection::prepareXMLUnplug(): this = " << this << endl;
202 unplugShortcuts( d->m_kaccel );
203
204 if( d->m_builderKAccel ) {
205 unplugShortcuts( d->m_builderKAccel );
206 delete d->m_builderKAccel;
207 d->m_builderKAccel = 0;
208 }
209*/
210}
211
212void KActionCollection::unplugShortcuts( KAccel* kaccel )
213{
214 qDebug("KActionCollection::unplugShortcuts has to be fixed");
215/*US
216 for ( QAsciiDictIterator<KAction> it( d->m_actionDict ); it.current(); ++it ) {
217 KAction* pAction = it.current();
218 pAction->removeKAccel( kaccel );
219 }
220
221 for( uint i = 0; i < d->m_docList.count(); i++ )
222 d->m_docList[i]->unplugShortcuts( kaccel );
223*/
224
225}
226
227/*void KActionCollection::addWidget( QWidget* w )
228{
229 if( !d->m_bOneKAccelOnly ) {
230 kdDebug(129) << "KActionCollection::addWidget( " << w << " ): this = " << this << endl;
231 for( uint i = 0; i < d->m_widgetList.count(); i++ ) {
232 if( d->m_widgetList[i] == w ) {
233 d->m_iWidgetCurrent = i;
234 return;
235 }
236 }
237 d->m_iWidgetCurrent = d->m_widgetList.count();
238 d->m_widgetList.append( w );
239 d->m_kaccelList.append( new KAccel( w, this, "KActionCollection-KAccel" ) );
240 }
241}
242
243void KActionCollection::removeWidget( QWidget* w )
244{
245 if( !d->m_bOneKAccelOnly ) {
246 kdDebug(129) << "KActionCollection::removeWidget( " << w << " ): this = " << this << endl;
247 for( uint i = 0; i < d->m_widgetList.count(); i++ ) {
248 if( d->m_widgetList[i] == w ) {
249 // Remove KAccel object from children.
250 KAccel* pKAccel = d->m_kaccelList[i];
251 for ( QAsciiDictIterator<KAction> it( d->m_actionDict ); it.current(); ++it ) {
252 KAction* pAction = it.current();
253 if ( pAction->m_parentCollection == this ) {
254 pAction->removeKAccel( pKAccel );
255 }
256 }
257 delete pKAccel;
258
259 d->m_widgetList.remove( d->m_widgetList.at( i ) );
260 d->m_kaccelList.remove( d->m_kaccelList.at( i ) );
261
262 if( d->m_iWidgetCurrent == (int)i )
263 d->m_iWidgetCurrent = -1;
264 else if( d->m_iWidgetCurrent > (int)i )
265 d->m_iWidgetCurrent--;
266 return;
267 }
268 }
269 kdWarning(129) << "KActionCollection::removeWidget( " << w << " ): widget not in list." << endl;
270 }
271}
272
273bool KActionCollection::ownsKAccel() const
274{
275 return d->m_bOneKAccelOnly;
276}
277
278uint KActionCollection::widgetCount() const
279{
280 return d->m_widgetList.count();
281}
282
283const KAccel* KActionCollection::widgetKAccel( uint i ) const
284{
285 return d->m_kaccelList[i];
286}*/
287
288//US we are using no accelerators so far. So just setup an empty implementation.
289KAccel* KActionCollection::kaccel()
290{
291 //if( d->m_kaccelList.count() > 0 )
292 // return d->m_kaccelList[d->m_iWidgetCurrent];
293 //else
294 // return 0;
295//US return d->m_kaccel;
296 return 0;
297}
298
299//US we are using no accelerators so far. So just setup an empty implementation.
300const KAccel* KActionCollection::kaccel() const
301{
302 //if( d->m_kaccelList.count() > 0 )
303 // return d->m_kaccelList[d->m_iWidgetCurrent];
304 //else
305 // return 0;
306 //USreturn d->m_kaccel;
307 return 0;
308}
309
310/*void KActionCollection::findMainWindow( QWidget *w )
311{
312 // Note: topLevelWidget() stops too early, we can't use it.
313 QWidget * tl = w;
314 while ( tl->parentWidget() ) // lookup parent and store
315 tl = tl->parentWidget();
316
317 KMainWindow * mw = dynamic_cast<KMainWindow *>(tl); // try to see if it's a kmainwindow
318 if (mw)
319 d->m_mainwindow = mw;
320 else
321 kdDebug(129) << "KAction::plugMainWindowAccel: Toplevel widget isn't a KMainWindow, can't plug accel. " << tl << endl;
322}*/
323
324void KActionCollection::_insert( KAction* action )
325{
326 char unnamed_name[100];
327 const char *name = action->name();
328 if( qstrcmp( name, "unnamed" ) == 0 )
329 {
330 sprintf(unnamed_name, "unnamed-%p", (void *)action);
331 name = unnamed_name;
332 }
333 KAction *a = d->m_actionDict[ name ];
334 if ( a == action )
335 return;
336
337 d->m_actionDict.insert( name, action );
338
339 emit inserted( action );
340}
341
342void KActionCollection::_remove( KAction* action )
343{
344 delete _take( action );
345}
346
347KAction* KActionCollection::_take( KAction* action )
348{
349 char unnamed_name[100];
350 const char *name = action->name();
351 if( qstrcmp( name, "unnamed" ) == 0 )
352 {
353 sprintf(unnamed_name, "unnamed-%p", (void *) action);
354 name = unnamed_name;
355 }
356
357 KAction *a = d->m_actionDict.take( name );
358 if ( !a || a != action )
359 return 0;
360
361 emit removed( action );
362 return a;
363}
364
365void KActionCollection::_clear()
366{
367 QAsciiDictIterator<KAction> it( d->m_actionDict );
368 while ( it.current() )
369 _remove( it.current() );
370}
371
372void KActionCollection::insert( KAction* action ) { _insert( action ); }
373void KActionCollection::remove( KAction* action ) { _remove( action ); }
374KAction* KActionCollection::take( KAction* action ) { return _take( action ); }
375void KActionCollection::clear() { _clear(); }
376KAccel* KActionCollection::accel() { return kaccel(); }
377const KAccel* KActionCollection::accel() const { return kaccel(); }
378KAccel* KActionCollection::builderKAccel() const { return d->m_builderKAccel; }
379
380KAction* KActionCollection::action( const char* name, const char* classname ) const
381{
382 KAction* pAction = 0;
383
384 if ( !classname && name )
385 pAction = d->m_actionDict[ name ];
386
387 else {
388 QAsciiDictIterator<KAction> it( d->m_actionDict );
389 for( ; it.current(); ++it )
390 {
391 if ( ( !name || strcmp( it.current()->name(), name ) == 0 ) &&
392 ( !classname || strcmp( it.current()->className(), classname ) == 0 ) ) {
393 pAction = it.current();
394 break;
395 }
396 }
397 }
398
399 if( !pAction ) {
400 for( uint i = 0; i < d->m_docList.count() && !pAction; i++ )
401 pAction = d->m_docList[i]->action( name, classname );
402 }
403
404 return pAction;
405}
406
407KAction* KActionCollection::action( int index ) const
408{
409 QAsciiDictIterator<KAction> it( d->m_actionDict );
410 it += index;
411 return it.current();
412// return d->m_actions.at( index );
413}
414/*US
415bool KActionCollection::readShortcutSettings( const QString& sConfigGroup, KConfigBase* pConfig )
416{
417 return KActionShortcutList(this).readSettings( sConfigGroup, pConfig );
418}
419
420bool KActionCollection::writeShortcutSettings( const QString& sConfigGroup, KConfigBase* pConfig ) const
421{
422 return KActionShortcutList((KActionCollection*)this).writeSettings( sConfigGroup, pConfig );
423}
424*/
425uint KActionCollection::count() const
426{
427 return d->m_actionDict.count();
428}
429
430QStringList KActionCollection::groups() const
431{
432 QStringList lst;
433
434 QAsciiDictIterator<KAction> it( d->m_actionDict );
435 for( ; it.current(); ++it )
436 if ( !it.current()->group().isEmpty() && !lst.contains( it.current()->group() ) )
437 lst.append( it.current()->group() );
438
439 return lst;
440}
441
442KActionPtrList KActionCollection::actions( const QString& group ) const
443{
444 KActionPtrList lst;
445
446 QAsciiDictIterator<KAction> it( d->m_actionDict );
447 for( ; it.current(); ++it )
448 if ( it.current()->group() == group )
449 lst.append( it.current() );
450 else if ( it.current()->group().isEmpty() && group.isEmpty() )
451 lst.append( it.current() );
452
453 return lst;
454}
455
456KActionPtrList KActionCollection::actions() const
457{
458 KActionPtrList lst;
459
460 QAsciiDictIterator<KAction> it( d->m_actionDict );
461 for( ; it.current(); ++it )
462 lst.append( it.current() );
463
464 return lst;
465}
466
467/*US we have no instance object. Use KGlobal instead
468void KActionCollection::setInstance( KInstance *instance )
469{
470 if ( instance )
471 d->m_instance = instance;
472qDebug("KActionCollection::setInstance has to be fixed");
473 else
474 d->m_instance = KGlobal::instance();
475}
476
477KInstance *KActionCollection::instance() const
478{
479 return d->m_instance;
480}
481*/
482
483/*US we have no XML facility in microkde
484void KActionCollection::setXMLFile( const QString& sXMLFile )
485{
486 d->m_sXMLFile = sXMLFile;
487}
488
489const QString& KActionCollection::xmlFile() const
490{
491 return d->m_sXMLFile;
492}
493*/
494
495void KActionCollection::setHighlightingEnabled( bool enable )
496{
497 d->m_highlight = enable;
498}
499
500bool KActionCollection::highlightingEnabled() const
501{
502 return d->m_highlight;
503}
504
505void KActionCollection::connectHighlight( QWidget *container, KAction *action )
506{
507 if ( !d->m_highlight )
508 return;
509
510 QPtrList<KAction> *actionList = d->m_dctHighlightContainers[ container ];
511
512 if ( !actionList )
513 {
514 actionList = new QPtrList<KAction>;
515
516 if ( container->inherits( "QPopupMenu" ) )
517 {
518 connect( container, SIGNAL( highlighted( int ) ),
519 this, SLOT( slotMenuItemHighlighted( int ) ) );
520 connect( container, SIGNAL( aboutToHide() ),
521 this, SLOT( slotMenuAboutToHide() ) );
522 }
523//US else if ( container->inherits( "KToolBar" ) )
524 else if ( container->inherits( "QToolBar" ) )
525 {
526 connect( container, SIGNAL( highlighted( int, bool ) ),
527 this, SLOT( slotToolBarButtonHighlighted( int, bool ) ) );
528 }
529
530 connect( container, SIGNAL( destroyed() ),
531 this, SLOT( slotDestroyed() ) );
532
533 d->m_dctHighlightContainers.insert( container, actionList );
534 }
535
536 actionList->append( action );
537}
538
539void KActionCollection::disconnectHighlight( QWidget *container, KAction *action )
540{
541 if ( !d->m_highlight )
542 return;
543
544 QPtrList<KAction> *actionList = d->m_dctHighlightContainers[ container ];
545
546 if ( !actionList )
547 return;
548
549 actionList->removeRef( action );
550
551 if ( actionList->count() == 0 )
552 d->m_dctHighlightContainers.remove( container );
553}
554
555void KActionCollection::slotMenuItemHighlighted( int id )
556{
557 if ( !d->m_highlight )
558 return;
559
560 if ( d->m_currentHighlightAction )
561 emit actionHighlighted( d->m_currentHighlightAction, false );
562
563 QWidget *container = static_cast<QWidget *>( const_cast<QObject *>( sender() ) );
564
565 d->m_currentHighlightAction = findAction( container, id );
566
567 if ( !d->m_currentHighlightAction )
568 {
569 if ( !d->m_statusCleared )
570 emit clearStatusText();
571 d->m_statusCleared = true;
572 return;
573 }
574
575 d->m_statusCleared = false;
576 emit actionHighlighted( d->m_currentHighlightAction );
577 emit actionHighlighted( d->m_currentHighlightAction, true );
578 emit actionStatusText( d->m_currentHighlightAction->toolTip() );
579}
580
581void KActionCollection::slotMenuAboutToHide()
582{
583 if ( d->m_currentHighlightAction )
584 emit actionHighlighted( d->m_currentHighlightAction, false );
585 d->m_currentHighlightAction = 0;
586
587 if ( !d->m_statusCleared )
588 emit clearStatusText();
589 d->m_statusCleared = true;
590}
591
592void KActionCollection::slotToolBarButtonHighlighted( int id, bool highlight )
593{
594 if ( !d->m_highlight )
595 return;
596
597 QWidget *container = static_cast<QWidget *>( const_cast<QObject *>( sender() ) );
598
599 KAction *action = findAction( container, id );
600
601 if ( !action )
602 {
603 d->m_currentHighlightAction = 0;
604 // use tooltip groups for toolbar status text stuff instead (Simon)
605// emit clearStatusText();
606 return;
607 }
608
609 emit actionHighlighted( action, highlight );
610
611 if ( highlight )
612 d->m_currentHighlightAction = action;
613 else
614 {
615 d->m_currentHighlightAction = 0;
616// emit clearStatusText();
617 }
618}
619
620void KActionCollection::slotDestroyed()
621{
622 d->m_dctHighlightContainers.remove( reinterpret_cast<void *>( const_cast<QObject *>(sender()) ) );
623}
624
625KAction *KActionCollection::findAction( QWidget *container, int id )
626{
627 QPtrList<KAction> *actionList = d->m_dctHighlightContainers[ reinterpret_cast<void *>( container ) ];
628
629 if ( !actionList )
630 return 0;
631
632 QPtrListIterator<KAction> it( *actionList );
633 for (; it.current(); ++it )
634 if ( it.current()->isPlugged( container, id ) )
635 return it.current();
636
637 return 0;
638}
639
640// KDE 4: remove
641KActionCollection KActionCollection::operator+(const KActionCollection &c ) const
642{
643 kdWarning(129) << "KActionCollection::operator+(): function is severely deprecated." << endl;
644 KActionCollection ret( *this );
645
646 QValueList<KAction *> actions = c.actions();
647 QValueList<KAction *>::ConstIterator it = actions.begin();
648 QValueList<KAction *>::ConstIterator end = actions.end();
649 for (; it != end; ++it )
650 ret.insert( *it );
651
652 return ret;
653}
654
655KActionCollection &KActionCollection::operator=( const KActionCollection &copy )
656{
657 kdWarning(129) << "KActionCollection::operator=(): function is severely deprecated." << endl;
658 //d->m_bOneKAccelOnly = copy.d->m_bOneKAccelOnly;
659 //d->m_iWidgetCurrent = copy.d->m_iWidgetCurrent;
660 //d->m_widgetList = copy.d->m_widgetList;
661 //d->m_kaccelList = copy.d->m_kaccelList;
662 d->m_widget = copy.d->m_widget;
663 d->m_kaccel = copy.d->m_kaccel;
664 d->m_actionDict = copy.d->m_actionDict;
665//US setInstance( copy.instance() );
666 return *this;
667}
668
669KActionCollection &KActionCollection::operator+=( const KActionCollection &c )
670{
671 kdWarning(129) << "KActionCollection::operator+=(): function is severely deprecated." << endl;
672 QAsciiDictIterator<KAction> it(c.d->m_actionDict);
673 for ( ; it.current(); ++it )
674 insert( it.current() );
675
676 return *this;
677}
678// KDE 4: remove end
679
680//---------------------------------------------------------------------
681// KActionShortcutList
682//---------------------------------------------------------------------
683/*US
684KActionShortcutList::KActionShortcutList( KActionCollection* pColl )
685: m_actions( *pColl )
686 { }
687KActionShortcutList::~KActionShortcutList()
688 { }
689uint KActionShortcutList::count() const
690 { return m_actions.count(); }
691QString KActionShortcutList::name( uint i ) const
692 { return m_actions.action(i)->name(); }
693QString KActionShortcutList::label( uint i ) const
694 { return m_actions.action(i)->text(); }
695QString KActionShortcutList::whatsThis( uint i ) const
696 { return m_actions.action(i)->whatsThis(); }
697const KShortcut& KActionShortcutList::shortcut( uint i ) const
698 { return m_actions.action(i)->shortcut(); }
699const KShortcut& KActionShortcutList::shortcutDefault( uint i ) const
700 { return m_actions.action(i)->shortcutDefault(); }
701bool KActionShortcutList::isConfigurable( uint i ) const
702 { return m_actions.action(i)->isShortcutConfigurable(); }
703bool KActionShortcutList::setShortcut( uint i, const KShortcut& cut )
704 { return m_actions.action(i)->setShortcut( cut ); }
705const KInstance* KActionShortcutList::instance() const
706 { return m_actions.instance(); }
707QVariant KActionShortcutList::getOther( Other, uint ) const
708 { return QVariant(); }
709bool KActionShortcutList::setOther( Other, uint, QVariant )
710 { return false; }
711
712bool KActionShortcutList::save() const
713{
714 kdDebug(129) << "KActionShortcutList::save(): xmlFile = " << m_actions.xmlFile() << endl;
715
716 if( m_actions.xmlFile().isEmpty() )
717 return writeSettings();
718
719 QString tagActionProp = QString::fromLatin1("ActionProperties");
720 QString tagAction = QString::fromLatin1("Action");
721 QString attrName = QString::fromLatin1("name");
722 QString attrShortcut = QString::fromLatin1("shortcut");
723 QString attrAccel = QString::fromLatin1("accel"); // Depricated attribute
724
725 // Read XML file
726 QString sXml( KXMLGUIFactory::readConfigFile( m_actions.xmlFile(), false, instance() ) );
727 QDomDocument doc;
728 doc.setContent( sXml );
729
730 // Process XML data
731
732 // first, lets see if we have existing properties
733 QDomElement elem;
734 QDomElement it = doc.documentElement();
735 // KXMLGUIFactory::removeDOMComments( it ); <-- What was this for? --ellis
736 it = it.firstChild().toElement();
737 for( ; !it.isNull(); it = it.nextSibling().toElement() ) {
738 if( it.tagName() == tagActionProp ) {
739 elem = it;
740 break;
741 }
742 }
743
744 // if there was none, create one
745 if( elem.isNull() ) {
746 elem = doc.createElement( tagActionProp );
747 doc.documentElement().appendChild( elem );
748 }
749
750 // now, iterate through our actions
751 uint nSize = count();
752 for( uint i = 0; i < nSize; i++ ) {
753 const QString& sName = name(i);
754
755 bool bSameAsDefault = (shortcut(i) == shortcutDefault(i));
756 //kdDebug(129) << "name = " << sName << " shortcut = " << shortcut(i).toStringInternal() << " def = " << shortcutDefault(i).toStringInternal() << endl;
757
758 // now see if this element already exists
759 QDomElement act_elem;
760 for( it = elem.firstChild().toElement(); !it.isNull(); it = it.nextSibling().toElement() ) {
761 if( it.attribute( attrName ) == sName ) {
762 act_elem = it;
763 break;
764 }
765 }
766
767 // nope, create a new one
768 if( act_elem.isNull() ) {
769 if( bSameAsDefault )
770 continue;
771 //kdDebug(129) << "\tnode doesn't exist." << endl;
772 act_elem = doc.createElement( tagAction );
773 act_elem.setAttribute( attrName, sName );
774 }
775
776 act_elem.removeAttribute( attrAccel );
777 if( bSameAsDefault ) {
778 act_elem.removeAttribute( attrShortcut );
779 //kdDebug(129) << "act_elem.attributes().count() = " << act_elem.attributes().count() << endl;
780 if( act_elem.attributes().count() == 1 )
781 elem.removeChild( act_elem );
782 } else {
783 act_elem.setAttribute( attrShortcut, shortcut(i).toStringInternal() );
784 elem.appendChild( act_elem );
785 }
786 }
787
788 // Write back to XML file
789 return KXMLGUIFactory::saveConfigFile( doc, m_actions.xmlFile(), instance() );
790}
791
792//---------------------------------------------------------------------
793// KActionPtrShortcutList
794//---------------------------------------------------------------------
795
796KActionPtrShortcutList::KActionPtrShortcutList( KActionPtrList& list )
797: m_actions( list )
798 { }
799KActionPtrShortcutList::~KActionPtrShortcutList()
800 { }
801uint KActionPtrShortcutList::count() const
802 { return m_actions.count(); }
803QString KActionPtrShortcutList::name( uint i ) const
804 { return m_actions[i]->name(); }
805QString KActionPtrShortcutList::label( uint i ) const
806 { return m_actions[i]->text(); }
807QString KActionPtrShortcutList::whatsThis( uint i ) const
808 { return m_actions[i]->whatsThis(); }
809const KShortcut& KActionPtrShortcutList::shortcut( uint i ) const
810 { return m_actions[i]->shortcut(); }
811const KShortcut& KActionPtrShortcutList::shortcutDefault( uint i ) const
812 { return m_actions[i]->shortcutDefault(); }
813bool KActionPtrShortcutList::isConfigurable( uint i ) const
814 { return m_actions[i]->isShortcutConfigurable(); }
815bool KActionPtrShortcutList::setShortcut( uint i, const KShortcut& cut )
816 { return m_actions[i]->setShortcut( cut ); }
817QVariant KActionPtrShortcutList::getOther( Other, uint ) const
818 { return QVariant(); }
819bool KActionPtrShortcutList::setOther( Other, uint, QVariant )
820 { return false; }
821bool KActionPtrShortcutList::save() const
822 { return false; }
823
824void KActionShortcutList::virtual_hook( int id, void* data )
825{ KShortcutList::virtual_hook( id, data ); }
826
827void KActionPtrShortcutList::virtual_hook( int id, void* data )
828{ KShortcutList::virtual_hook( id, data ); }
829*/
830
831void KActionCollection::virtual_hook( int, void* )
832{ /*BASE::virtual_hook( id, data );*/ }
833
834/* vim: et sw=2 ts=2
835 */
836
837/*US
838#include "kactioncollection.moc"
839*/
diff --git a/microkde/kdeui/kactioncollection.h b/microkde/kdeui/kactioncollection.h
new file mode 100644
index 0000000..b9466d0
--- a/dev/null
+++ b/microkde/kdeui/kactioncollection.h
@@ -0,0 +1,329 @@
1/* This file is part of the KDE libraries
2 Copyright (C) 1999 Reginald Stadlbauer <reggie@kde.org>
3 (C) 1999 Simon Hausmann <hausmann@kde.org>
4 (C) 2000 Nicolas Hadacek <haadcek@kde.org>
5 (C) 2000 Kurt Granroth <granroth@kde.org>
6 (C) 2000 Michael Koch <koch@kde.org>
7 (C) 2001 Holger Freyther <freyther@kde.org>
8 (C) 2002 Ellis Whitehead <ellis@kde.org>
9
10 This library is free software; you can redistribute it and/or
11 modify it under the terms of the GNU Library General Public
12 License version 2 as published by the Free Software Foundation.
13
14 This library is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Library General Public License for more details.
18
19 You should have received a copy of the GNU Library General Public License
20 along with this library; see the file COPYING.LIB. If not, write to
21 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22 Boston, MA 02111-1307, USA.
23*/
24//$Id$
25
26#ifndef __kactioncollection_h__
27#define __kactioncollection_h__
28
29#include <kaction.h>
30
31//US #include <qkeysequence.h>
32#include <qobject.h>
33//US#include <qvaluelist.h>
34//US#include <qguardedptr.h>
35//US #include <kguiitem.h>
36//US#include <kshortcut.h>
37//US#include <kstdaction.h>
38//US#include <kicontheme.h>
39
40//USclass QMenuBar;
41//USclass QPopupMenu;
42//USclass QComboBox;
43//USclass QPoint;
44//USclass QIconSet;
45//USclass QString;
46//USclass KToolBar;
47
48//USclass KAccel;
49//USclass KAccelActions;
50//USclass KConfig;
51//USclass KConfigBase;
52//USclass KURL;
53//USclass KInstance;
54//USclass KToolBar;
55//USclass KActionCollection;
56//USclass KPopupMenu;
57//USclass KMainWindow;
58
59//US added inclidefiles
60class QWidget;
61
62
63typedef QValueList<KAction *> KActionPtrList;
64
65/**
66 * A managed set of KAction objects.
67 */
68class KActionCollection : public QObject
69{
70 friend class KAction;
71 friend class KXMLGUIClient;
72
73 Q_OBJECT
74public:
75 KActionCollection( QWidget *parent, const char *name = 0/*US , KInstance *instance = 0 */);
76 /**
77 * Use this constructor if you want the collection's actions to restrict
78 * their accelerator keys to @p watch rather than the @p parent. If
79 * you don't require shortcuts, you can pass a null to the @p watch parameter.
80 */
81 KActionCollection( QWidget *watch, QObject* parent, const char *name = 0/*US, KInstance *instance = 0 */);
82 KActionCollection( const KActionCollection &copy );
83 virtual ~KActionCollection();
84
85 /**
86 * This sets the widget to which the keyboard shortcuts should be attached.
87 * You only need to call this if a null pointer was passed in the constructor.
88 */
89 virtual void setWidget( QWidget *widget );
90
91 /**
92 * This indicates whether new actions which are created in this collection
93 * should have their keyboard shortcuts automatically connected on
94 * construction. Set to 'false' if you will be loading XML-based settings.
95 * This is automatically done by KParts. The default is 'true'.
96 * @see isAutoConnectShortcuts()
97 */
98 void setAutoConnectShortcuts( bool );
99
100 /**
101 * This indicates whether new actions which are created in this collection
102 * have their keyboard shortcuts automatically connected on
103 * construction.
104 * @see setAutoConnectShortcuts()
105 */
106 bool isAutoConnectShortcuts();
107
108 /**
109 * This sets the default shortcut scope for new actions created in this
110 * collection. The default is ScopeUnspecified. Ideally the default
111 * would have been ScopeWidget, but that would cause some backwards
112 * compatibility problems.
113 */
114 //void setDefaultScope( KAction::Scope );
115
116 /**
117 * Doc/View model. This lets you add the action collection of a document
118 * to a view's action collection.
119 */
120 bool addDocCollection( KActionCollection* pDoc );
121
122 /** Returns the number of widgets which this collection is associated with. */
123 //uint widgetCount() const;
124
125 /**
126 * Returns true if the collection has its own KAccel object. This will be
127 * the case if it was constructed with a valid widget ptr or if setWidget()
128 * was called.
129 */
130 //bool ownsKAccel() const;
131
132 /** @deprecated Deprecated because of ambiguous name. Use kaccel() */
133 virtual KAccel* accel();
134 /** @deprecated Deprecated because of ambiguous name. Use kaccel() */
135 virtual const KAccel* accel() const;
136
137 /** Returns the KAccel object of the most recently set widget. */
138 KAccel* kaccel();
139 /** Returns the KAccel object of the most recently set widget. Const version for convenience. */
140 const KAccel* kaccel() const;
141
142 /** @internal, for KAction::kaccelCurrent() */
143 KAccel* builderKAccel() const;
144 /** Returns the KAccel object associated with widget #. */
145 //KAccel* widgetKAccel( uint i );
146 //const KAccel* widgetKAccel( uint i ) const;
147
148 /** Returns the number of actions in the collection */
149 virtual uint count() const;
150 bool isEmpty() const { return count() == 0; }
151 /**
152 * Return the KAction* at position "index" in the action collection.
153 * @see count()
154 */
155 virtual KAction* action( int index ) const;
156 /**
157 * Find an action (optionally, of a given subclass of KAction) in the action collection.
158 * @param name Name of the KAction.
159 * @param classname Name of the KAction subclass.
160 * @return A pointer to the first KAction in the collection which matches the parameters or
161 * null if nothing matches.
162 */
163 virtual KAction* action( const char* name, const char* classname = 0 ) const;
164
165 /** Returns a list of all the groups of all the KActions in this action collection.
166 * @see KAction::group()
167 * @see KAction::setGroup()
168 */
169 virtual QStringList groups() const;
170 /**
171 * Returns the list of actions in a particular managed by this action collection.
172 * @param group The name of the group.
173 */
174 virtual KActionPtrList actions( const QString& group ) const;
175 /** Returns the list of actions managed by this action collection. */
176 virtual KActionPtrList actions() const;
177
178 /**
179 * Used for reading shortcut configuration from a non-XML rc file.
180 */
181//US bool readShortcutSettings( const QString& sConfigGroup = QString::null, KConfigBase* pConfig = 0 );
182 /**
183 * Used for writing shortcut configuration to a non-XML rc file.
184 */
185//US bool writeShortcutSettings( const QString& sConfigGroup = QString::null, KConfigBase* pConfig = 0 ) const;
186
187//US void setInstance( KInstance *instance );
188 /** The instance with which this class is associated. */
189//US KInstance *instance() const;
190
191 /**
192 * Use this to tell the KActionCollection what rc file its configuration
193 * is stored in.
194 */
195 void setXMLFile( const QString& );
196 /** The rc file in which the current configuration is stored. */
197 const QString& xmlFile() const;
198
199 /**
200 * Enable highlighting notification for specific KActions.
201 * @see connectHighlight()
202 * @see disconnectHighlight()
203 * @see actionHighlighted()
204 * @see actionHighlighted()
205 * @see highlightingEnabled()
206 */
207 void setHighlightingEnabled( bool enable );
208 /**
209 * Return whether highlighting notifications are enabled.
210 * @see connectHighlight()
211 * @see disconnectHighlight()
212 * @see actionHighlighted()
213 * @see setHighlightingEnabled()
214 * @see actionHighlighted()
215 */
216 bool highlightingEnabled() const;
217
218 /**
219 * Call this function if you want to receive a signal whenever a KAction is highlighted in a menu or a toolbar.
220 * @param container A container in which the KAction is plugged (must inherit QPopupMenu or KToolBar)
221 * @param action The action you are interested in
222 * @see disconnectHighlight()
223 * @see actionHighlighted()
224 * @see setHighlightingEnabled()
225 * @see highlightingEnabled()
226 * @see actionHighlighted()
227 */
228 void connectHighlight( QWidget *container, KAction *action );
229 /**
230 * Disconnect highlight notifications for a particular pair of contianer and action.
231 * @param container A container in which the KAction is plugged (must inherit QPopupMenu or KToolBar)
232 * @param action The action you are interested in
233 * @see connectHighlight()
234 * @see actionHighlighted()
235 * @see setHighlightingEnabled()
236 * @see highlightingEnabled()
237 * @see actionHighlighted()
238 */
239 void disconnectHighlight( QWidget *container, KAction *action );
240
241signals:
242 void inserted( KAction* );
243 void removed( KAction* );
244
245 /** Emitted when "action" is highlighted.
246 * @see connectHighlight()
247 * @see disconnectHighlight()
248 * @see actionHighlighted()
249 * @see setHighlightingEnabled()
250 * @see highlightingEnabled()
251 */
252 void actionHighlighted( KAction *action );
253 /** Emitted when "action" is highlighed or loses highlighting.
254 * @see connectHighlight()
255 * @see disconnectHighlight()
256 * @see actionHighlighted()
257 * @see setHighlightingEnabled()
258 * @see highlightingEnabled()
259 */
260 void actionHighlighted( KAction *action, bool highlight );
261
262 void actionStatusText( const QString &text );
263 void clearStatusText();
264
265private:
266 /**
267 * @internal Only to be called by KXMLGUIFactory::addClient().
268 * When actions are being connected, KAction needs to know what
269 * widget it should connect widget-scope actions to, and what
270 * main window it should connect
271 */
272 void beginXMLPlug( QWidget *widget );
273 void endXMLPlug();
274 /** @internal. Only to be called by KXMLGUIFactory::removeClient() */
275 void prepareXMLUnplug();
276 void unplugShortcuts( KAccel* kaccel );
277
278 void _clear();
279 void _insert( KAction* );
280 void _remove( KAction* );
281 KAction* _take( KAction* );
282
283private slots:
284 void slotMenuItemHighlighted( int id );
285 void slotToolBarButtonHighlighted( int id, bool highlight );
286 void slotMenuAboutToHide();
287 void slotDestroyed();
288
289private:
290 KAction *findAction( QWidget *container, int id );
291
292#ifndef KDE_NO_COMPAT
293public:
294 KActionCollection( QObject *parent, const char *name = 0 /*US, KInstance *instance = 0 */);
295
296 void insert( KAction* );
297
298 /**
299 * @deprecated Removes an action from the collection and deletes it.
300 * @param action The KAction to remove.
301 */
302 void remove( KAction* action );
303
304 /**
305 * @deprecated Removes an action from the collection.
306 * @return NULL if not found else returns action.
307 * @param action the KAction to remove.
308 */
309 KAction* take( KAction* action );
310
311 KActionCollection operator+ ( const KActionCollection& ) const;
312 KActionCollection& operator= ( const KActionCollection& );
313 KActionCollection& operator+= ( const KActionCollection& );
314
315public slots:
316 /**
317 * Clears the entire actionCollection, deleting all actions.
318 * @see #remove
319 */
320 void clear();
321#endif // !KDE_NO_COMPAT
322protected:
323 virtual void virtual_hook( int id, void* data );
324private:
325 class KActionCollectionPrivate;
326 KActionCollectionPrivate *d;
327};
328
329#endif
diff --git a/microkde/kdeui/kbuttonbox.cpp b/microkde/kdeui/kbuttonbox.cpp
new file mode 100644
index 0000000..16206e8
--- a/dev/null
+++ b/microkde/kdeui/kbuttonbox.cpp
@@ -0,0 +1,300 @@
1/* This file is part of the KDE libraries
2 Copyright (C) 1997 Mario Weilguni (mweilguni@sime.com)
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA.
18*/
19
20/*
21 * KButtonBox class
22 *
23 * A container widget for buttons. Uses Qt layout control to place the
24 * buttons, can handle both vertical and horizontal button placement.
25*
26 * HISTORY
27 *
28 * 03/08/2000 Mario Weilguni <mweilguni@kde.org>
29 * Removed all those long outdated Motif stuff
30 * Improved and clarified some if conditions (easier to understand)
31 *
32 * 11/13/98 Reginald Stadlbauer <reggie@kde.org>
33 * Now in Qt 1.4x motif default buttons have no extra width/height anymore.
34 * So the KButtonBox doesn't add this width/height to default buttons anymore
35 * which makes the buttons look better.
36 *
37 * 01/17/98 Mario Weilguni <mweilguni@sime.com>
38 * Fixed a bug in sizeHint()
39 * Improved the handling of Motif default buttons
40 *
41 * 01/09/98 Mario Weilguni <mweilguni@sime.com>
42 * The last button was to far right away from the right/bottom border.
43 * Fixed this. Removed old code. Buttons get now a minimum width.
44 * Programmer may now override minimum width and height of a button.
45 *
46 */
47
48//US #include "kbuttonbox.moc"
49
50#include <kbuttonbox.h>
51#include <qpushbutton.h>
52#include <qptrlist.h>
53#include <assert.h>
54
55#define minButtonWidth 50
56
57class KButtonBox::Item {
58public:
59 QPushButton *button;
60 bool noexpand;
61 unsigned short stretch;
62 unsigned short actual_size;
63};
64
65template class QPtrList<KButtonBox::Item>;
66
67class KButtonBoxPrivate {
68public:
69 unsigned short border;
70 unsigned short autoborder;
71 unsigned short orientation;
72 bool activated;
73 QPtrList<KButtonBox::Item> buttons;
74};
75
76KButtonBox::KButtonBox(QWidget *parent, Orientation _orientation,
77 int border, int autoborder)
78 : QWidget(parent)
79{
80 data = new KButtonBoxPrivate;
81 assert(data != 0);
82
83 data->orientation = _orientation;
84 data->border = border;
85 data->autoborder = autoborder < 0 ? border : autoborder;
86 data->buttons.setAutoDelete(TRUE);
87}
88
89KButtonBox::~KButtonBox() {
90 delete data;
91}
92
93QPushButton *KButtonBox::addButton(const QString& text, bool noexpand) {
94 Item *item = new Item;
95
96 item->button = new QPushButton(text, this);
97 item->noexpand = noexpand;
98 data->buttons.append(item);
99 item->button->adjustSize();
100
101 return item->button;
102}
103
104 QPushButton *
105KButtonBox::addButton(
106 const QString & text,
107 QObject * receiver,
108 const char * slot,
109 bool noexpand
110)
111{
112 QPushButton * pb = addButton(text, noexpand);
113
114 if ((0 != receiver) && (0 != slot))
115 QObject::connect(pb, SIGNAL(clicked()), receiver, slot);
116
117 return pb;
118}
119
120
121void KButtonBox::addStretch(int scale) {
122 if(scale > 0) {
123 Item *item = new Item;
124 item->button = 0;
125 item->noexpand = FALSE;
126 item->stretch = scale;
127 data->buttons.append(item);
128 }
129}
130
131void KButtonBox::layout() {
132 // resize all buttons
133 QSize bs = bestButtonSize();
134
135 for(unsigned int i = 0; i < data->buttons.count(); i++) {
136 Item *item = data->buttons.at(i);
137 QPushButton *b = item->button;
138 if(b != 0) {
139 if(item->noexpand)
140 b->setFixedSize(buttonSizeHint(b));
141 else
142 b->setFixedSize(bs);
143 }
144 }
145
146 setMinimumSize(sizeHint());
147}
148
149void KButtonBox::placeButtons() {
150 unsigned int i;
151
152 if(data->orientation == Horizontal) {
153 // calculate free size and stretches
154 int fs = width() - 2 * data->border;
155 int stretch = 0;
156 for(i = 0; i < data->buttons.count(); i++) {
157 Item *item = data->buttons.at(i);
158 if(item->button != 0) {
159 fs -= item->button->width();
160
161 // Last button?
162 if(i != data->buttons.count() - 1)
163 fs -= data->autoborder;
164 } else
165 stretch +=item->stretch;
166 }
167
168 // distribute buttons
169 int x_pos = data->border;
170 for(i = 0; i < data->buttons.count(); i++) {
171 Item *item = data->buttons.at(i);
172 if(item->button != 0) {
173 QPushButton *b = item->button;
174 b->move(x_pos, (height() - b->height()) / 2);
175
176 x_pos += b->width() + data->autoborder;
177 } else
178 x_pos += (int)((((double)fs) * item->stretch) / stretch);
179 }
180 } else { // VERTICAL
181 // calcualte free size and stretches
182 int fs = height() - 2 * data->border;
183 int stretch = 0;
184 for(i = 0; i < data->buttons.count(); i++) {
185 Item *item = data->buttons.at(i);
186 if(item->button != 0)
187 fs -= item->button->height() + data->autoborder;
188 else
189 stretch +=item->stretch;
190 }
191
192 // distribute buttons
193 int y_pos = data->border;
194 for(i = 0; i < data->buttons.count(); i++) {
195 Item *item = data->buttons.at(i);
196 if(item->button != 0) {
197 QPushButton *b = item->button;
198 b->move((width() - b->width()) / 2, y_pos);
199
200 y_pos += b->height() + data->autoborder;
201 } else
202 y_pos += (int)((((double)fs) * item->stretch) / stretch);
203 }
204 }
205}
206
207void KButtonBox::resizeEvent(QResizeEvent *) {
208 placeButtons();
209}
210
211QSize KButtonBox::bestButtonSize() const {
212 QSize s(0, 0);
213 unsigned int i;
214
215 // calculate optimal size
216 for(i = 0; i < data->buttons.count(); i++) {
217 KButtonBox *that = (KButtonBox*)this; // to remove the const ;(
218 Item *item = that->data->buttons.at(i);
219 QPushButton *b = item->button;
220
221 if(b != 0 && !item->noexpand) {
222 QSize bs = buttonSizeHint(b);
223
224 if(bs.width() > s.width())
225 s.setWidth(bs.width());
226 if(bs.height() > s.height())
227 s.setHeight(bs.height());
228 }
229 }
230
231 return s;
232}
233
234QSize KButtonBox::sizeHint() const {
235 unsigned int i, dw;
236
237 if(data->buttons.count() == 0)
238 return QSize(0, 0);
239 else {
240 dw = 2 * data->border;
241
242 QSize bs = bestButtonSize();
243 for(i = 0; i < data->buttons.count(); i++) {
244 KButtonBox *that = (KButtonBox*)this;
245 Item *item = that->data->buttons.at(i);
246 QPushButton *b = item->button;
247 if(b != 0) {
248 QSize s;
249 if(item->noexpand)
250 s = that->buttonSizeHint(b);
251 else
252 s = bs;
253
254 if(data->orientation == Horizontal)
255 dw += s.width();
256 else
257 dw += s.height();
258
259 if( i != data->buttons.count() - 1 )
260 dw += data->autoborder;
261 }
262 }
263
264 if(data->orientation == Horizontal)
265 return QSize(dw, bs.height() + 2 * data->border);
266 else
267 return QSize(bs.width() + 2 * data->border, dw);
268 }
269}
270
271QSizePolicy KButtonBox::sizePolicy() const
272{
273 return data->orientation == Horizontal?
274 QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Fixed ) :
275 QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Minimum );
276}
277
278/*
279 * Returns the best size for a button. If a button is less than
280 * minButtonWidth pixels wide, return minButtonWidth pixels
281 * as minimum width
282 */
283QSize KButtonBox::buttonSizeHint(QPushButton *b) const {
284 QSize s = b->sizeHint();
285 QSize ms = b->minimumSize();
286 if(s.width() < minButtonWidth)
287 s.setWidth(minButtonWidth);
288
289 // allows the programmer to override the settings
290 if(ms.width() > s.width())
291 s.setWidth(ms.width());
292 if(ms.height() > s.height())
293 s.setHeight(ms.height());
294
295 return s;
296}
297
298void KButtonBox::virtual_hook( int, void* )
299{ /*BASE::virtual_hook( id, data );*/ }
300
diff --git a/microkde/kdeui/kbuttonbox.h b/microkde/kdeui/kbuttonbox.h
new file mode 100644
index 0000000..1104366
--- a/dev/null
+++ b/microkde/kdeui/kbuttonbox.h
@@ -0,0 +1,139 @@
1/* This file is part of the KDE libraries
2 Copyright (C) 1997 Mario Weilguni (mweilguni@sime.com)
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA.
18*/
19
20#ifndef __KBUTTONBOX__H__
21#define __KBUTTONBOX__H__
22
23#include <qwidget.h>
24class QPushButton;
25
26class KButtonBoxPrivate;
27/**
28 * Container widget for buttons.
29 *
30 * This class uses Qt layout control to place the buttons; can handle
31 * both vertical and horizontal button placement. The default border
32 * is now @p 0 (making it easier to deal with layouts). The space
33 * between buttons is now more Motif compliant.
34 *
35 * @author Mario Weilguni <mweilguni@sime.com>
36 * @version $Id$
37 **/
38
39class KButtonBox : public QWidget
40{
41 Q_OBJECT
42
43public:
44 /**
45 * Create an empty container for buttons.
46 *
47 * If @p _orientation is @p Vertical, the buttons inserted with
48 * @ref addButton() are laid out from top to bottom, otherwise they
49 * are laid out from left to right.
50 */
51 KButtonBox(QWidget *parent, Orientation _orientation = Horizontal,
52 int border = 0, int _autoborder = 6);
53
54 /**
55 * Free private data field
56 */
57 ~KButtonBox();
58
59 /**
60 * @return The minimum size needed to fit all buttons.
61 *
62 * This size is
63 * calculated by the width/height of all buttons plus border/autoborder.
64 */
65 virtual QSize sizeHint() const;
66 /**
67 * @reimplemented
68 */
69 virtual QSizePolicy sizePolicy() const;
70 /**
71 * @reimplemented
72 */
73 virtual void resizeEvent(QResizeEvent *);
74
75 /**
76 * Add a new @ref QPushButton.
77 *
78 * @param noexpand If @p noexpand is @p false, the width
79 * of the button is adjusted to fit the other buttons (the maximum
80 * of all buttons is taken). If @p noexpand is @p true, the width of this
81 * button will be set to the minimum width needed for the given text).
82 *
83 * @return A pointer to the new button.
84 */
85 QPushButton *addButton(const QString& text, bool noexpand = FALSE);
86
87 /**
88 * Add a new @ref QPushButton.
89 *
90 * @param receiver An object to connect to.
91 * @param slot A Qt slot to connect the 'clicked()' signal to.
92 * @param noexpand If @p noexpand is @p false, the width
93 * of the button is adjusted to fit the other buttons (the maximum
94 * of all buttons is taken). If @p noexpand @p true, the width of this
95 * button will be set to the minimum width needed for the given text).
96 *
97 * @return A pointer to the new button.
98 */
99 QPushButton *addButton(const QString& text, QObject * receiver, const char * slot, bool noexpand = FALSE);
100
101 /**
102 * Add a stretch to the buttonbox.
103 *
104 * Can be used to separate buttons. That is, if you add the
105 * buttons OK and Cancel, add a stretch, and then add the button Help,
106 * the buttons OK and Cancel will be left-aligned (or top-aligned
107 * for vertical) whereas Help will be right-aligned (or
108 * bottom-aligned for vertical).
109 *
110 * @see QBoxLayout
111 */
112 void addStretch(int scale = 1);
113
114 /**
115 * This function must be called @em once after all buttons have been
116 * inserted.
117 *
118 * It will start layout control.
119 */
120 void layout();
121
122public: // as PrivateData needs Item, it has to be exported
123 class Item;
124protected:
125 /**
126 * @return the best size for a button. Checks all buttons and takes
127 * the maximum width/height.
128 */
129 QSize bestButtonSize() const;
130 void placeButtons();
131 QSize buttonSizeHint(QPushButton *) const;
132
133protected:
134 virtual void virtual_hook( int id, void* data );
135private:
136 KButtonBoxPrivate *data;
137};
138
139#endif
diff --git a/microkde/kdeui/kcmodule.cpp b/microkde/kdeui/kcmodule.cpp
new file mode 100644
index 0000000..915cd0f
--- a/dev/null
+++ b/microkde/kdeui/kcmodule.cpp
@@ -0,0 +1,106 @@
1/*
2 This file is part of the KDE libraries
3
4 Copyright (c) 2001 Michael Goffioul <goffioul@imec.be>
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
15
16 You should have received a copy of the GNU Library General Public License
17 along with this library; see the file COPYING.LIB. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.
20
21*/
22
23#include "kcmodule.h"
24//US#include <kinstance.h>
25#include <kglobal.h>
26#include <klocale.h>
27#include <kdebug.h>
28
29class KCModulePrivate
30{
31public:
32//US KInstance *_instance;
33 QString _rootOnlyMsg;
34 bool _useRootOnlyMsg;
35 bool _hasOwnInstance;
36};
37
38KCModule::KCModule(QWidget *parent, const char *name, const QStringList &)
39 : QWidget(parent, name), _btn(Help|Default|Apply)
40{
41 kdDebug() << "KCModule " << name << endl;
42 d = new KCModulePrivate;
43 d->_useRootOnlyMsg = true;
44/*US
45 d->_instance = new KInstance(name);
46 if (name && strlen(name)) {
47 d->_instance = new KInstance(name);
48 KGlobal::locale()->insertCatalogue(name);
49 } else
50 d->_instance = new KInstance("kcmunnamed");
51*/
52 d->_hasOwnInstance = true;
53//US KGlobal::setActiveInstance(this->instance());
54}
55
56/*US
57KCModule::KCModule(KInstance *instance, QWidget *parent, const QStringList & )
58 : QWidget(parent, instance ? instance->instanceName().data() : 0), _btn(Help|Default|Apply)
59{
60 kdDebug() << "KCModule instance " << (instance ? instance->instanceName().data() : "none") << endl;
61 d = new KCModulePrivate;
62 d->_useRootOnlyMsg = true;
63 d->_instance = instance;
64 KGlobal::locale()->insertCatalogue(instance->instanceName());
65 d->_hasOwnInstance = false;
66 KGlobal::setActiveInstance(this->instance());
67}
68*/
69KCModule::~KCModule()
70{
71/*US
72 if (d->_hasOwnInstance)
73 delete d->_instance;
74*/
75 delete d;
76}
77
78void KCModule::setRootOnlyMsg(const QString& msg)
79{
80 d->_rootOnlyMsg = msg;
81}
82
83QString KCModule::rootOnlyMsg() const
84{
85 return d->_rootOnlyMsg;
86}
87
88void KCModule::setUseRootOnlyMsg(bool on)
89{
90 d->_useRootOnlyMsg = on;
91}
92
93bool KCModule::useRootOnlyMsg() const
94{
95 return d->_useRootOnlyMsg;
96}
97/*US
98KInstance *KCModule::instance() const
99{
100 return d->_instance;
101}
102*/
103void KCModule::virtual_hook( int, void* )
104{ /*BASE::virtual_hook( id, data );*/ }
105
106//US #include "kcmodule.moc"
diff --git a/microkde/kdeui/kcmodule.h b/microkde/kdeui/kcmodule.h
new file mode 100644
index 0000000..90a87c9
--- a/dev/null
+++ b/microkde/kdeui/kcmodule.h
@@ -0,0 +1,266 @@
1/*
2 This file is part of the KDE libraries
3
4 Copyright (c) 1999 Matthias Hoelzer-Kluepfel <hoelzer@kde.org>
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
15
16 You should have received a copy of the GNU Library General Public License
17 along with this library; see the file COPYING.LIB. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.
20
21*/
22#ifndef __KCMODULE_H__
23#define __KCMODULE_H__
24
25#include <qwidget.h>
26#include <qstringlist.h>
27//USclass KAboutData;
28class KCModulePrivate;
29//US class KInstance;
30
31/**
32 * The base class for control center modules.
33 *
34 * Starting from KDE 2.0, control center modules are realized as shared
35 * libraries that are loaded into the control center at runtime.
36 *
37 * The module in principle is a simple widget displaying the
38 * item to be changed. The module has a very small interface.
39 *
40 * All the necessary glue logic and the GUI bells and whistles
41 * are provided by the control center and must not concern
42 * the module author.
43 *
44 * To write a config module, you have to create a library
45 * that contains at one factory function like this:
46 *
47 * <pre>
48 * #include <kgenericfactory.h>
49 *
50 * typedef KGenericFactory<YourKCModule, QWidget> YourKCModuleFactory;
51 * K_EXPORT_COMPONENT_FACTORY( yourLibName, YourKCModuleFactory("name_of_the_po_file") );
52 * </pre>
53 *
54 * The parameter "name_of_the_po_file" has to correspond with the messages target
55 * that you created in your Makefile.am.
56 *
57 * See kdebase/kcontrol/HOWTO for more detailed documentation.
58 *
59 * @author Matthias Hoelzer-Kluepfel <hoelzer@kde.org>
60 */
61
62class KCModule : public QWidget
63{
64 Q_OBJECT
65
66public:
67
68 /**
69 * An enumeration type for the buttons used by this module.
70 * You should only use Help, Default and Apply. The rest is obsolete.
71 *
72 * @see KCModule::buttons @see KCModule::setButtons
73 */
74 enum Button {Help=1, Default=2, Apply=16,
75 Reset=4, /* obsolete, do not use! */
76 Cancel=8, /* obsolete, do not use! */
77 Ok=32, /* obsolete, do not use! */
78 SysDefault=64 /* obsolete, do not use! */ };
79
80 /*
81 * Base class for all KControlModules.
82 * Make sure you have a QStringList argument in your
83 * implementation.
84 */
85 KCModule(QWidget *parent=0, const char *name=0, const QStringList &args=QStringList() );
86
87//US KCModule(KInstance *instance, QWidget *parent=0, const QStringList &args=QStringList() );
88
89 /*
90 * Destroys the module.
91 */
92 ~KCModule();
93
94 /**
95 * Load the configuration data into the module.
96 *
97 * The load method sets the user interface elements of the
98 * module to reflect the current settings stored in the
99 * configuration files.
100 *
101 * This method is invoked whenever the module should read its configuration
102 * (most of the times from a config file) and update the user interface.
103 * This happens when the user clicks the "Reset" button in the control
104 * center, to undo all of his changes and restore the currently valid
105 * settings. NOTE that this is not called after the modules is loaded,
106 * so you probably want to call this method in the constructor.
107 */
108 virtual void load() {};
109
110 /**
111 * Save the configuration data.
112 *
113 * The save method stores the config information as shown
114 * in the user interface in the config files.
115 *
116 * If necessary, this method also updates the running system,
117 * e.g. by restarting applications.
118 *
119 * save is called when the user clicks "Apply" or "Ok".
120 */
121 virtual void save() {};
122
123 /**
124 * Sets the configuration to sensible default values.
125 *
126 * This method is called when the user clicks the "Default"
127 * button. It should set the display to useful values.
128 */
129 virtual void defaults() {};
130
131 /**
132 * Set the configuration to system default values.
133 *
134 * This method is called when the user clicks the "System-Default"
135 * button. It should set the display to the system default values.
136 *
137 * NOTE: The default behaviour is to call defaults().
138 */
139 virtual void sysdefaults() { defaults(); };
140
141 /**
142 * Return a quick-help text.
143 *
144 * This method is called when the module is docked.
145 * The quick-help text should contain a short description of the module and
146 * links to the module's help files. You can use QML formating tags in the text.
147 *
148 * NOTE: Please make sure the quick help text gets translated (use i18n()).
149 */
150 virtual QString quickHelp() const { return QString::null; };
151
152 /**
153 * Returns a the KAboutData for this module
154 * This is generally only called for the KBugReport.
155 * Override and have it return a pointer to a constant
156 */
157//US virtual const KAboutData *aboutData() const { return 0; }
158
159 /**
160 * Indicate which buttons will be used.
161 *
162 * The return value is a value or'ed together from
163 * the Button enumeration type.
164 *
165 * @see KCModule::setButtons
166 */
167 int buttons() const { return _btn; };
168
169 /**
170 * Get the RootOnly message for this module.
171 *
172 * When the module must be run as root, or acts differently
173 * for root and a normal user, it is sometimes useful to
174 * customize the message that appears at the top of the module
175 * when used as a normal user. This function returns this
176 * customized message. If none has been set, a default message
177 * will be used.
178 *
179 * @see KCModule::setRootOnlyMsg
180 */
181 QString rootOnlyMsg() const;
182
183 /**
184 * Tell if KControl should show a RootOnly message when run as
185 * a normal user.
186 *
187 * In some cases, the module don't want a RootOnly message to
188 * appear (for example if it has already one). This function
189 * tells KControl if a RootOnly message should be shown
190 *
191 * @see KCModule::setUseRootOnlyMsg
192 */
193 bool useRootOnlyMsg() const;
194
195
196//US KInstance *instance() const;
197
198signals:
199
200 /**
201 * Indicate that the state of the modules contents has changed.
202 *
203 * This signal is emitted whenever the state of the configuration
204 * shown in the module changes. It allows the control center to
205 * keep track of unsaved changes.
206 *
207 */
208 void changed(bool state);
209
210 /**
211 * Indicate that the module's quickhelp has changed.
212 *
213 * Emit this signal whenever the module's quickhelp changes.
214 * Modules implemented as tabbed dialogs might want to implement
215 * per-tab quickhelp for example.
216 *
217 */
218 void quickHelpChanged();
219
220protected:
221
222 /**
223 * Sets the buttons to display.
224 *
225 * Help: shows a "Help" button.
226 * Default: shows a "Use Defaults" button
227 * Apply: in kcontrol this will show an "Apply" and "Reset" button
228 * in kcmshell this will show an "Ok", "Apply" and "Cancel" button
229 *
230 * If Apply is not specified, kcmshell will show a "Close" button.
231 *
232 * @see KCModule::buttons
233 */
234 void setButtons(int btn) { _btn = btn; };
235
236 /**
237 * Sets the RootOnly message.
238 *
239 * This message will be shown at the top of the module of the
240 * corresponding desktop file contains the line X-KDE-RootOnly=true.
241 * If no message is set, a default one will be used.
242 *
243 * @see KCModule::rootOnlyMessage
244 */
245 void setRootOnlyMsg(const QString& msg);
246
247 /**
248 * Change wether or not the RootOnly message should be shown.
249 *
250 * Following the value of @p on, the RootOnly message will be
251 * shown or not.
252 *
253 * @see KCModule::useRootOnlyMsg
254 */
255 void setUseRootOnlyMsg(bool on);
256
257private:
258
259 int _btn;
260protected:
261 virtual void virtual_hook( int id, void* data );
262private:
263 KCModulePrivate *d;
264};
265
266#endif
diff --git a/microkde/kdeui/kguiitem.cpp b/microkde/kdeui/kguiitem.cpp
new file mode 100644
index 0000000..828c5e6
--- a/dev/null
+++ b/microkde/kdeui/kguiitem.cpp
@@ -0,0 +1,205 @@
1/* This file is part of the KDE libraries
2 Copyright (C) 2001 Holger Freyther (freyher@yahoo.com)
3 based on ideas from Martijn and Simon
4 many thanks to Simon
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License version 2 as published by the Free Software Foundation.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21#include <qregexp.h>
22#include <qstring.h>
23#include <qiconset.h>
24#include <qpixmap.h>
25
26#include <assert.h>
27//US #include <kiconloader.h>
28#include <kdebug.h>
29
30#include "kguiitem.h"
31
32class KGuiItem::KGuiItemPrivate
33{
34public:
35 KGuiItemPrivate()
36 {
37 m_enabled = true;
38 m_hasIcon = false;
39 }
40
41 KGuiItemPrivate( const KGuiItemPrivate &rhs )
42 {
43 (*this ) = rhs;
44 }
45
46 KGuiItemPrivate &operator=( const KGuiItemPrivate &rhs )
47 {
48 m_text = rhs.m_text;
49 m_iconSet = rhs.m_iconSet;
50 m_iconName = rhs.m_iconName;
51 m_toolTip = rhs.m_toolTip;
52 m_whatsThis = rhs.m_whatsThis;
53 m_statusText = rhs.m_statusText;
54 m_enabled = rhs.m_enabled;
55 m_hasIcon = rhs.m_hasIcon;
56
57 return *this;
58 }
59
60 QString m_text;
61 QString m_toolTip;
62 QString m_whatsThis;
63 QString m_statusText;
64 QString m_iconName;
65 QIconSet m_iconSet;
66 bool m_hasIcon : 1;
67 bool m_enabled : 1;
68};
69
70
71KGuiItem::KGuiItem() {
72 d = new KGuiItemPrivate;
73}
74
75KGuiItem::KGuiItem( const QString &text, const QString &iconName,
76 const QString &toolTip, const QString &whatsThis )
77{
78 d = new KGuiItemPrivate;
79 d->m_text = text;
80 d->m_toolTip = toolTip;
81 d->m_whatsThis = whatsThis;
82 setIconName( iconName );
83}
84
85KGuiItem::KGuiItem( const QString &text, const QIconSet &iconSet,
86 const QString &toolTip, const QString &whatsThis )
87{
88 d = new KGuiItemPrivate;
89 d->m_text = text;
90 d->m_toolTip = toolTip;
91 d->m_whatsThis = whatsThis;
92 setIconSet( iconSet );
93}
94
95KGuiItem::KGuiItem( const KGuiItem &rhs )
96 : d( 0 )
97{
98 (*this) = rhs;
99}
100
101KGuiItem &KGuiItem::operator=( const KGuiItem &rhs ) {
102 if ( d == rhs.d )
103 return *this;
104
105 assert( rhs.d );
106
107 delete d;
108 d = new KGuiItemPrivate( *rhs.d );
109
110 return *this;
111}
112
113KGuiItem::~KGuiItem() {
114 delete d;
115}
116
117QString KGuiItem::text() const {
118 return d->m_text;
119}
120QString KGuiItem::plainText() const {
121 QString stripped( d->m_text );
122 stripped.replace( QRegExp( "&(?!&)" ), QString::null );
123
124 return stripped;
125}
126
127QIconSet KGuiItem::iconSet( KIcon::Group group, int size /*US, KInstance* instance */ ) const
128{
129 if( d->m_hasIcon )
130 {
131 if( !d->m_iconName.isEmpty())
132 {
133// some caching here would(?) come handy
134//US return instance->iconLoader()->loadIconSet( d->m_iconName, group, size );
135 return KGlobal::iconLoader()->loadIconSet( d->m_iconName);
136// here is a little problem that with delayed icon loading
137// we can't check if the icon really exists ... so what ...
138// if( set.isNull() )
139// {
140// d->m_hasIcon = false;
141// return QIconSet();
142// }
143// return set;
144 }
145 else
146 {
147 return d->m_iconSet;
148 }
149 }
150 else
151 return QIconSet();
152}
153
154QString KGuiItem::iconName() const
155{
156 return d->m_iconName;
157}
158
159QString KGuiItem::toolTip() const {
160 return d->m_toolTip;
161}
162QString KGuiItem::whatsThis() const {
163 return d->m_whatsThis;
164}
165
166bool KGuiItem::isEnabled() const
167{
168 return d->m_enabled;
169}
170
171bool KGuiItem::hasIcon() const
172{
173 return d->m_hasIcon;
174}
175
176void KGuiItem::setText( const QString &text ) {
177 d->m_text=text;
178}
179
180void KGuiItem::setIconSet( const QIconSet &iconset )
181{
182 d->m_iconSet = iconset;
183 d->m_iconName = QString::null;
184 d->m_hasIcon = !iconset.isNull();
185}
186
187void KGuiItem::setIconName( const QString &iconName )
188{
189 d->m_iconName = iconName;
190 d->m_iconSet = QIconSet();
191 d->m_hasIcon = !iconName.isEmpty();
192}
193
194void KGuiItem::setToolTip( const QString &toolTip) {
195 d->m_toolTip = toolTip;
196}
197void KGuiItem::setWhatsThis( const QString &whatsThis ) {
198 d->m_whatsThis = whatsThis;
199}
200void KGuiItem::setEnabled( bool enabled ){
201 d->m_enabled = enabled;
202}
203
204/* vim: et sw=4
205 */
diff --git a/microkde/kdeui/kguiitem.h b/microkde/kdeui/kguiitem.h
new file mode 100644
index 0000000..0079bb4
--- a/dev/null
+++ b/microkde/kdeui/kguiitem.h
@@ -0,0 +1,87 @@
1/* This file is part of the KDE libraries
2 Copyright (C) 2001 Holger Freyther (freyher@yahoo.com)
3 based on ideas from Martijn and Simon
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License version 2 as published by the Free Software Foundation.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA.
18
19 Many thanks to Simon tronical Hausmann
20*/
21
22#ifndef __kguiitem_h__
23#define __kguiitem_h__
24
25#include <qstring.h>
26#include <qiconset.h>
27#include <qpixmap.h>
28#include <qvaluelist.h>
29//US#include <kicontheme.h>
30#include <kglobal.h>
31
32//US added the following files
33#include <kiconloader.h>
34
35class KGuiItem
36{
37public:
38 KGuiItem();
39
40 KGuiItem( const QString &text,
41 const QString &iconName = QString::null,
42 const QString &toolTip = QString::null,
43 const QString &whatsThis = QString::null );
44
45 KGuiItem( const QString &text, const QIconSet &iconSet,
46 const QString &toolTip = QString::null,
47 const QString &whatsThis = QString::null );
48
49 KGuiItem( const KGuiItem &rhs );
50 KGuiItem &operator=( const KGuiItem &rhs );
51
52 ~KGuiItem();
53
54 QString text() const;
55 QString plainText() const;
56 QIconSet iconSet( KIcon::Group, int size = 0/*US , KInstance* instance = KGlobal::instance()*/) const;
57
58#ifndef KDE_NO_COMPAT
59 QIconSet iconSet() const { return iconSet( KIcon::Small); }
60#endif
61
62 QString iconName() const;
63 QString toolTip() const;
64 QString whatsThis() const;
65 bool isEnabled() const;
66 bool hasIcon() const;
67#ifndef KDE_NO_COMPAT
68 bool hasIconSet() const { return hasIcon(); }
69#endif
70
71 void setText( const QString &text );
72 void setIconSet( const QIconSet &iconset );
73 void setIconName( const QString &iconName );
74 void setToolTip( const QString &tooltip );
75 void setWhatsThis( const QString &whatsThis );
76 void setEnabled( bool enable );
77
78private:
79 class KGuiItemPrivate;
80 KGuiItemPrivate *d;
81};
82
83/* vim: et sw=4
84 */
85
86#endif
87
diff --git a/microkde/kdeui/kjanuswidget.cpp b/microkde/kdeui/kjanuswidget.cpp
new file mode 100644
index 0000000..7d25854
--- a/dev/null
+++ b/microkde/kdeui/kjanuswidget.cpp
@@ -0,0 +1,1176 @@
1/* This file is part of the KDE Libraries
2 * Copyright (C) 1999-2000 Espen Sand (espensa@online.no)
3 * Copyright (C) 2003 Ravikiran Rajagopal (ravi@kde.org)
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; see the file COPYING.LIB. If not, write to
17 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
19 */
20
21#include <qpixmap.h>
22#include <qbitmap.h>
23#include <qlayout.h>
24#include <qlabel.h>
25#include <qwidgetstack.h>
26#include <qtabwidget.h>
27#include <qlistview.h>
28#include <qhbox.h>
29#include <qvbox.h>
30#include <qgrid.h>
31#include <qpainter.h>
32#include <qobjectlist.h>
33
34/*US
35#include <qbitmap.h>
36#include <qgrid.h>
37#include <qhbox.h>
38#include <qheader.h>
39#include <qlabel.h>
40#include <qlayout.h>
41#include <qobjectlist.h>
42#include <qpixmap.h>
43#include <qsplitter.h>
44#include <qtabwidget.h>
45#include <qvbox.h>
46#include <qwidgetstack.h>
47#include <qpainter.h>
48#include <qstyle.h>
49
50#include <kapplication.h>
51#include <klocale.h>
52#include <kglobal.h>
53#include <kglobalsettings.h>
54#include <kseparator.h>
55#include <kdebug.h>
56#include "kjanuswidget.h"
57#include <klistview.h>
58
59*/
60
61#include <kseparator.h>
62#include <kdialog.h> // Access to some static members
63#include <kdebug.h>
64#include <klistview.h>
65
66#include "kjanuswidget.h"
67
68class KJanusWidget::IconListItem : public QListBoxItem
69{
70 public:
71 IconListItem( QListBox *listbox, const QPixmap &pixmap,
72 const QString &text );
73 virtual int height( const QListBox *lb ) const;
74 virtual int width( const QListBox *lb ) const;
75 int expandMinimumWidth( int width );
76
77 protected:
78 const QPixmap &defaultPixmap();
79 void paint( QPainter *painter );
80
81 private:
82 QPixmap mPixmap;
83 int mMinimumWidth;
84};
85
86class KJanusWidget::KJanusWidgetPrivate
87{
88public:
89 KJanusWidgetPrivate() : mNextPageIndex(0) { }
90
91 int mNextPageIndex; // The next page index.
92
93 // Dictionary for multipage modes.
94 QMap<int,QWidget*> mIntToPage;
95 // Reverse dictionary. Used because showPage() may be performance critical.
96 QMap<QWidget*,int> mPageToInt;
97 // Dictionary of title string associated with page.
98 QMap<int, QString> mIntToTitle;
99};
100
101template class QPtrList<QListViewItem>;
102
103
104KJanusWidget::KJanusWidget( QWidget *parent, const char *name, int face )
105 : QWidget( parent, name ),
106 mValid(false), mPageList(0),
107 mTitleList(0), mFace(face), mTitleLabel(0), mActivePageWidget(0),
108 mShowIconsInTreeList(false), d(0)
109{
110 QVBoxLayout *topLayout = new QVBoxLayout( this );
111 if( mFace == TreeList || mFace == IconList )
112 {
113 d = new KJanusWidgetPrivate;
114
115 QFrame *page = 0;
116 if( mFace == TreeList )
117 {
118 //US
119 qDebug("KJanusWidget::KJanusWidget TreeList not implemented yet");
120/*US
121 QSplitter *splitter = new QSplitter( this );
122 topLayout->addWidget( splitter, 10 );
123 mTreeListResizeMode = QSplitter::KeepSize;
124
125 mTreeList = new KListView( splitter );
126 mTreeList->addColumn( QString::null );
127 mTreeList->header()->hide();
128 mTreeList->setRootIsDecorated(true);
129 mTreeList->setSorting( -1 );
130 connect( mTreeList, SIGNAL(selectionChanged()), SLOT(slotShowPage()) );
131 connect( mTreeList, SIGNAL(clicked(QListViewItem *)), SLOT(slotItemClicked(QListViewItem *)));
132
133 //
134 // Page area. Title at top with a separator below and a pagestack using
135 // all available space at bottom.
136 //
137 QFrame *p = new QFrame( splitter );
138
139 QHBoxLayout *hbox = new QHBoxLayout( p, 0, 0 );
140 hbox->addSpacing( KDialog::marginHint() );
141
142 page = new QFrame( p );
143 hbox->addWidget( page, 10 );
144*/
145 }
146 else
147 {
148 QHBoxLayout *hbox = new QHBoxLayout( topLayout );
149 mIconList = new IconListBox( this );
150
151 QFont listFont( mIconList->font() );
152 listFont.setBold( true );
153 mIconList->setFont( listFont );
154
155 mIconList->verticalScrollBar()->installEventFilter( this );
156 hbox->addWidget( mIconList );
157 connect( mIconList, SIGNAL(selectionChanged()), SLOT(slotShowPage()));
158 hbox->addSpacing( KDialog::marginHint() );
159 page = new QFrame( this );
160 hbox->addWidget( page, 10 );
161 }
162
163 //
164 // Rest of page area. Title at top with a separator below and a
165 // pagestack using all available space at bottom.
166 //
167
168 QVBoxLayout *vbox = new QVBoxLayout( page, 0, KDialog::spacingHint() );
169
170 mTitleLabel = new QLabel( QString::fromLatin1("Empty page"), page, "KJanusWidgetTitleLabel" );
171 vbox->addWidget( mTitleLabel );
172
173 QFont titleFont( mTitleLabel->font() );
174 titleFont.setBold( true );
175 mTitleLabel->setFont( titleFont );
176
177 mTitleSep = new KSeparator( page );
178 mTitleSep->setFrameStyle( QFrame::HLine|QFrame::Plain );
179 vbox->addWidget( mTitleSep );
180
181 mPageStack = new QWidgetStack( page );
182 connect(mPageStack, SIGNAL(aboutToShow(QWidget *)),
183 SIGNAL(aboutToShowPage(QWidget *)));
184 vbox->addWidget( mPageStack, 10 );
185 }
186 else if( mFace == Tabbed )
187 {
188 d = new KJanusWidgetPrivate;
189
190 mTabControl = new QTabWidget( this );
191 mTabControl->setMargin (KDialog::marginHint());
192 topLayout->addWidget( mTabControl, 10 );
193 }
194 else if( mFace == Swallow )
195 {
196 mSwallowPage = new QWidget( this );
197 topLayout->addWidget( mSwallowPage, 10 );
198 }
199 else
200 {
201 mFace = Plain;
202 mPlainPage = new QFrame( this );
203 topLayout->addWidget( mPlainPage, 10 );
204 }
205/*US
206 if ( kapp )
207 connect(kapp,SIGNAL(kdisplayFontChanged()),SLOT(slotFontChanged()));
208*/
209 mValid = true;
210 setSwallowedWidget(0); // Set default size if 'mFace' is Swallow.
211}
212
213
214KJanusWidget::~KJanusWidget()
215{
216
217/*US the destroyed signal caused a segmentation fault while closing the dialog and destructing
218 all pages. Why not just remove all pages in the destructor??
219*/
220// LR we have all subwidgets with parent-child relation
221// LR we do not need to delete here anything by the private class
222/*
223 if( mFace == Tabbed )
224 {
225 QMap<QWidget*,int>::Iterator it;
226 for (it = d->mPageToInt.begin(); it != d->mPageToInt.end(); ++it) {
227 QObject*page = (QObject*)it.key();
228 pageGone(page);
229 }
230 }
231 else
232 qDebug("KJanusWidget::~KJanusWidget so far ");
233*/
234//US end
235
236 delete d;
237
238
239}
240
241
242bool KJanusWidget::isValid() const
243{
244 return( mValid );
245}
246
247
248QFrame *KJanusWidget::plainPage()
249{
250 return( mPlainPage );
251}
252
253
254int KJanusWidget::face() const
255{
256 return( mFace );
257}
258
259QWidget *KJanusWidget::FindParent()
260{
261 if( mFace == Tabbed ) {
262 return mTabControl;
263 }
264 else {
265 return this;
266 }
267}
268
269QFrame *KJanusWidget::addPage( const QStringList &items, const QString &header,
270 const QPixmap &pixmap )
271{
272 if( mValid == false )
273 {
274 kdDebug() << "addPage: Invalid object" << endl;
275 return( 0 );
276 }
277
278 QFrame *page = new QFrame( FindParent(), "page" );
279 addPageWidget( page, items, header, pixmap );
280
281 return page;
282}
283
284void KJanusWidget::pageGone( QObject *obj )
285{
286// QObject* obj = (QObject*)sender();
287 removePage( static_cast<QWidget*>( obj ) );
288}
289
290void KJanusWidget::slotReopen( QListViewItem * item )
291{
292 if( item )
293 item->setOpen( true );
294}
295
296QFrame *KJanusWidget::addPage( const QString &itemName, const QString &header,
297 const QPixmap &pixmap )
298{
299 QStringList items;
300 items << itemName;
301 return addPage(items, header, pixmap);
302}
303
304
305
306QVBox *KJanusWidget::addVBoxPage( const QStringList &items,
307 const QString &header,
308 const QPixmap &pixmap )
309{
310 if( mValid == false )
311 {
312 qDebug("addPage: Invalid object ");
313
314 return( 0 );
315 }
316
317 QVBox *page = new QVBox(FindParent() , "vbox_page" );
318 page->setSpacing( KDialog::spacingHintSmall() );
319 addPageWidget( page, items, header, pixmap );
320
321 return page;
322}
323
324QVBox *KJanusWidget::addVBoxPage( const QString &itemName,
325 const QString &header,
326 const QPixmap &pixmap )
327{
328 QStringList items;
329 items << itemName;
330 return addVBoxPage(items, header, pixmap);
331}
332
333QHBox *KJanusWidget::addHBoxPage( const QStringList &items,
334 const QString &header,
335 const QPixmap &pixmap )
336{
337 if( mValid == false ) {
338 kdDebug() << "addPage: Invalid object" << endl;
339 return( 0 );
340 }
341
342 QHBox *page = new QHBox(FindParent(), "hbox_page");
343 page->setSpacing( KDialog::spacingHint() );
344 addPageWidget( page, items, header, pixmap );
345
346 return page;
347}
348
349QHBox *KJanusWidget::addHBoxPage( const QString &itemName,
350 const QString &header,
351 const QPixmap &pixmap )
352{
353 QStringList items;
354 items << itemName;
355 return addHBoxPage(items, header, pixmap);
356}
357
358QGrid *KJanusWidget::addGridPage( int n, QGrid::Direction dir,
359 const QStringList &items,
360 const QString &header,
361 const QPixmap &pixmap )
362{
363 if( mValid == false )
364 {
365 kdDebug() << "addPage: Invalid object" << endl;
366 return( 0 );
367 }
368
369 QGrid *page = new QGrid( n, dir, FindParent(), "page" );
370 page->setSpacing( KDialog::spacingHint() );
371 addPageWidget( page, items, header, pixmap );
372
373 return page;
374}
375
376
377QGrid *KJanusWidget::addGridPage( int n, QGrid::Direction dir,
378 const QString &itemName,
379 const QString &header,
380 const QPixmap &pixmap )
381{
382 QStringList items;
383 items << itemName;
384 return addGridPage(n, dir, items, header, pixmap);
385}
386
387void KJanusWidget::InsertTreeListItem(const QStringList &items, const QPixmap &pixmap, QFrame *page)
388{
389 bool isTop = true;
390 QListViewItem *curTop = 0, *child, *last, *newChild;
391 unsigned int index = 1;
392 QStringList curPath;
393
394 for ( QStringList::ConstIterator it = items.begin(); it != items.end(); ++it, index++ ) {
395 QString name = (*it);
396 bool isPath = ( index != items.count() );
397
398 // Find the first child.
399 if (isTop) {
400 child = mTreeList->firstChild();
401 }
402 else {
403 child = curTop->firstChild();
404 }
405
406 // Now search for a child with the current Name, and if it we doesn't
407 // find it, then remember the location of the last child.
408 for (last = 0; child && child->text(0) != name ; last = child, child = child->nextSibling());
409
410 if (last == 0 && child == 0) {
411 // This node didn't have any children at all, lets just insert the
412 // new child.
413 if (isTop)
414 newChild = new QListViewItem(mTreeList, name);
415 else
416 newChild = new QListViewItem(curTop, name);
417
418 }
419 else if (child != 0) {
420 // we found the given name in this child.
421 if (!isPath) {
422 kdDebug() << "The element inserted was already in the TreeList box!" << endl;
423 return;
424 }
425 else {
426 // Ok we found the folder
427 newChild = child;
428 }
429 }
430 else {
431 // the node had some children, but we didn't find the given name
432 if (isTop)
433 newChild = new QListViewItem(mTreeList, last, name);
434 else
435 newChild = new QListViewItem(curTop, last, name);
436 }
437
438 // Now make the element expandable if it is a path component, and make
439 // ready for next loop
440 if (isPath) {
441 newChild->setExpandable(true);
442 curTop = newChild;
443 isTop = false;
444 curPath << name;
445
446 QString key = curPath.join("_/_");
447 if (mFolderIconMap.contains(key)) {
448 QPixmap p = mFolderIconMap[key];
449 newChild->setPixmap(0,p);
450 }
451 }
452 else {
453 if (mShowIconsInTreeList) {
454 newChild->setPixmap(0, pixmap);
455 }
456 mTreeListToPageStack.insert(newChild, page);
457 }
458 }
459}
460
461void KJanusWidget::addPageWidget( QFrame *page, const QStringList &items,
462 const QString &header,const QPixmap &pixmap )
463{
464/*US the following signal causes a segmentation fault while closing the dialog.
465 Why not just remove all pages in the destructor??
466*/
467//US connect(page, SIGNAL(destroyed(QObject*)), this, SLOT(pageGone(QObject*)));
468// we have the SIGNAL(destroyed(QObject*) only in Qt3
469#ifdef DESKTOP_VERSION
470 // connect(page, SIGNAL(destroyed(QObject*)), this, SLOT(pageGone(QObject*)));
471#endif
472 if( mFace == Tabbed )
473 {
474 mTabControl->addTab (page, items.last());
475 d->mIntToPage[d->mNextPageIndex] = static_cast<QWidget*>(page);
476 d->mPageToInt[static_cast<QWidget*>(page)] = d->mNextPageIndex;
477 d->mNextPageIndex++;
478 }
479 else if( mFace == TreeList || mFace == IconList )
480 {
481 d->mIntToPage[d->mNextPageIndex] = static_cast<QWidget*>(page);
482 d->mPageToInt[static_cast<QWidget*>(page)] = d->mNextPageIndex;
483 mPageStack->addWidget( page, 0 );
484
485 if (items.count() == 0) {
486 kdDebug() << "Invalid QStringList, with zero items" << endl;
487 return;
488 }
489
490 if( mFace == TreeList )
491 {
492 InsertTreeListItem(items, pixmap, page);
493 }
494 else // mFace == IconList
495 {
496 QString itemName = items.last();
497 IconListItem *item = new IconListItem( mIconList, pixmap, itemName );
498 mIconListToPageStack.insert(item, page);
499 mIconList->invalidateHeight();
500 mIconList->invalidateWidth();
501
502 if (mIconList->isVisible())
503 mIconList->updateWidth();
504 }
505
506 //
507 // Make sure the title label is sufficiently wide
508 //
509 QString lastName = items.last();
510 const QString &title = (!header.isNull() ? header : lastName);
511 QRect r = mTitleLabel->fontMetrics().boundingRect( title );
512 if( mTitleLabel->minimumWidth() < r.width() )
513 {
514 mTitleLabel->setMinimumWidth( r.width() );
515 }
516 d->mIntToTitle[d->mNextPageIndex] = title;
517 if( d->mIntToTitle.count() == 1 )
518 {
519 showPage(0);
520 }
521 d->mNextPageIndex++;
522 }
523 else
524 {
525 kdDebug() << "KJanusWidget::addPageWidget: can only add a page in Tabbed, TreeList or IconList modes" << endl;
526 }
527
528}
529
530void KJanusWidget::setFolderIcon(const QStringList &path, const QPixmap &pixmap)
531{
532 QString key = path.join("_/_");
533 mFolderIconMap.insert(key,pixmap);
534}
535
536
537
538bool KJanusWidget::setSwallowedWidget( QWidget *widget )
539{
540 if( mFace != Swallow || mValid == false )
541 {
542 return( false );
543 }
544
545 //
546 // Remove current layout and make a new.
547 //
548 if( mSwallowPage->layout() != 0 )
549 {
550 delete mSwallowPage->layout();
551 }
552 QGridLayout *gbox = new QGridLayout( mSwallowPage, 1, 1, 0 );
553
554 //
555 // Hide old children
556 //
557 QObjectList *l = (QObjectList*)mSwallowPage->children(); // silence please
558 for( uint i=0; i < l->count(); i++ )
559 {
560 QObject *o = l->at(i);
561 if( o->isWidgetType() )
562 {
563 ((QWidget*)o)->hide();
564 }
565 }
566
567 //
568 // Add new child or make default size
569 //
570 if( widget == 0 )
571 {
572 gbox->addRowSpacing(0,100);
573 gbox->addColSpacing(0,100);
574 mSwallowPage->setMinimumSize(100,100);
575 }
576 else
577 {
578 if( widget->parent() != mSwallowPage )
579 {
580 widget->reparent( mSwallowPage, 0, QPoint(0,0) );
581 }
582 gbox->addWidget(widget, 0, 0 );
583 gbox->activate();
584 mSwallowPage->setMinimumSize( widget->minimumSize() );
585 }
586
587 return( true );
588}
589
590bool KJanusWidget::slotShowPage()
591{
592 if( mValid == false )
593 {
594 return( false );
595 }
596
597 if( mFace == TreeList )
598 {
599 QListViewItem *node = mTreeList->selectedItem();
600 if( node == 0 ) { return( false ); }
601
602 QWidget *stackItem = mTreeListToPageStack[node];
603 // Make sure to call through the virtual function showPage(int)
604 return showPage(d->mPageToInt[stackItem]);
605 }
606 else if( mFace == IconList )
607 {
608 QListBoxItem *node = mIconList->item( mIconList->currentItem() );
609 if( node == 0 ) { return( false ); }
610 QWidget *stackItem = mIconListToPageStack[node];
611 // Make sure to call through the virtual function showPage(int)
612 return showPage(d->mPageToInt[stackItem]);
613 }
614
615 return( false );
616}
617
618
619bool KJanusWidget::showPage( int index )
620{
621 if( d == 0 || mValid == false )
622 {
623 return( false );
624 }
625 else
626 {
627 return showPage(d->mIntToPage[index]);
628 }
629}
630
631
632bool KJanusWidget::showPage( QWidget *w )
633{
634 if( w == 0 || mValid == false )
635 {
636 return( false );
637 }
638
639 if( mFace == TreeList || mFace == IconList )
640 {
641 mPageStack->raiseWidget( w );
642 mActivePageWidget = w;
643
644 int index = d->mPageToInt[w];
645 mTitleLabel->setText( d->mIntToTitle[index] );
646 if( mFace == TreeList )
647 {
648 QMap<QListViewItem *, QWidget *>::Iterator it;
649 for (it = mTreeListToPageStack.begin(); it != mTreeListToPageStack.end(); ++it){
650 QListViewItem *key = it.key();
651 QWidget *val = it.data();
652 if (val == w) {
653 mTreeList->setSelected(key, true );
654 break;
655 }
656 }
657 }
658 else
659 {
660 QMap<QListBoxItem *, QWidget *>::Iterator it;
661 for (it = mIconListToPageStack.begin(); it != mIconListToPageStack.end(); ++it){
662 QListBoxItem *key = it.key();
663 QWidget *val = it.data();
664 if (val == w) {
665 mIconList->setSelected( key, true );
666 break;
667 }
668 }
669 }
670 }
671 else if( mFace == Tabbed )
672 {
673 mTabControl->showPage(w);
674 mActivePageWidget = w;
675 }
676 else
677 {
678 return( false );
679 }
680
681 return( true );
682}
683
684
685int KJanusWidget::activePageIndex() const
686{
687 if( mFace == TreeList) {
688 QListViewItem *node = mTreeList->selectedItem();
689 if( node == 0 ) { return -1; }
690 QWidget *stackItem = mTreeListToPageStack[node];
691 return d->mPageToInt[stackItem];
692 }
693 else if (mFace == IconList) {
694 QListBoxItem *node = mIconList->item( mIconList->currentItem() );
695 if( node == 0 ) { return( false ); }
696 QWidget *stackItem = mIconListToPageStack[node];
697 return d->mPageToInt[stackItem];
698 }
699 else if( mFace == Tabbed ) {
700 QWidget *widget = mTabControl->currentPage();
701 return( widget == 0 ? -1 : d->mPageToInt[widget] );
702 }
703 else {
704 return( -1 );
705 }
706}
707
708
709int KJanusWidget::pageIndex( QWidget *widget ) const
710{
711 if( widget == 0 )
712 {
713 return( -1 );
714 }
715 else if( mFace == TreeList || mFace == IconList )
716 {
717 return( d->mPageToInt[widget] );
718 }
719 else if( mFace == Tabbed )
720 {
721 //
722 // The user gets the real page widget with addVBoxPage(), addHBoxPage()
723 // and addGridPage() but not with addPage() which returns a child of
724 // the toplevel page. addPage() returns a QFrame so I check for that.
725 //
726 if( widget->isA("QFrame") )
727 {
728 return( d->mPageToInt[widget->parentWidget()] );
729 }
730 else
731 {
732 return( d->mPageToInt[widget] );
733 }
734 }
735 else
736 {
737 return( -1 );
738 }
739}
740/*US not yet implemented
741void KJanusWidget::slotFontChanged()
742{
743 if( mTitleLabel != 0 )
744 {
745 mTitleLabel->setFont( KGlobalSettings::generalFont() );
746 QFont titleFont( mTitleLabel->font() );
747 titleFont.setBold( true );
748 mTitleLabel->setFont( titleFont );
749 }
750
751 if( mFace == IconList )
752 {
753 QFont listFont( mIconList->font() );
754 listFont.setBold( true );
755 mIconList->setFont( listFont );
756 mIconList->invalidateHeight();
757 mIconList->invalidateWidth();
758 }
759}
760*/
761
762// makes the treelist behave like the list of kcontrol
763void KJanusWidget::slotItemClicked(QListViewItem *it)
764{
765 if(it && (it->childCount()>0))
766 it->setOpen(!it->isOpen());
767}
768
769void KJanusWidget::setFocus()
770{
771 if( mValid == false ) { return; }
772 if( mFace == TreeList )
773 {
774 mTreeList->setFocus();
775 }
776 if( mFace == IconList )
777 {
778 mIconList->setFocus();
779 }
780 else if( mFace == Tabbed )
781 {
782 mTabControl->setFocus();
783 }
784 else if( mFace == Swallow )
785 {
786 mSwallowPage->setFocus();
787 }
788 else if( mFace == Plain )
789 {
790 mPlainPage->setFocus();
791 }
792}
793
794
795QSize KJanusWidget::minimumSizeHint() const
796{
797 if( mFace == TreeList || mFace == IconList )
798 {
799 QSize s1( KDialog::spacingHint(), KDialog::spacingHint()*2 );
800 QSize s2(0,0);
801 QSize s3(0,0);
802 QSize s4( mPageStack->sizeHint() );
803
804 if( mFace == TreeList )
805 {
806/*US
807 s1.rwidth() += style().pixelMetric( QStyle::PM_SplitterWidth );
808 s2 = mTreeList->minimumSize();
809*/
810 }
811 else
812 {
813 mIconList->updateMinimumHeight();
814 mIconList->updateWidth();
815 s2 = mIconList->minimumSize();
816 }
817
818 if( mTitleLabel->isVisible() == true )
819 {
820 s3 += mTitleLabel->sizeHint();
821 s3.rheight() += mTitleSep->minimumSize().height();
822 }
823
824 //
825 // Select the tallest item. It has only effect in IconList mode
826 //
827 int h1 = s1.rheight() + s3.rheight() + s4.height();
828 int h2 = QMAX( h1, s2.rheight() );
829
830 return( QSize( s1.width()+s2.width()+QMAX(s3.width(),s4.width()), h2 ) );
831 }
832 else if( mFace == Tabbed )
833 {
834 return( mTabControl->sizeHint() );
835 }
836 else if( mFace == Swallow )
837 {
838 return( mSwallowPage->minimumSize() );
839 }
840 else if( mFace == Plain )
841 {
842 return( mPlainPage->sizeHint() );
843 }
844 else
845 {
846 return( QSize( 100, 100 ) ); // Should never happen though.
847 }
848
849}
850
851
852QSize KJanusWidget::sizeHint() const
853{
854 return( minimumSizeHint() );
855}
856
857
858void KJanusWidget::setTreeListAutoResize( bool state )
859{
860 if( mFace == TreeList )
861 {
862/*US
863 mTreeListResizeMode = state == false ?
864 QSplitter::KeepSize : QSplitter::Stretch;
865 QSplitter *splitter = (QSplitter*)(mTreeList->parentWidget());
866 splitter->setResizeMode( mTreeList, mTreeListResizeMode );
867*/
868 }
869}
870
871
872void KJanusWidget::setIconListAllVisible( bool state )
873{
874 if( mFace == IconList )
875 {
876 mIconList->setShowAll( state );
877 }
878}
879
880void KJanusWidget::setShowIconsInTreeList( bool state )
881{
882 mShowIconsInTreeList = state;
883}
884
885void KJanusWidget::setRootIsDecorated( bool state )
886{
887 if( mFace == TreeList ) {
888 mTreeList->setRootIsDecorated(state);
889 }
890}
891
892void KJanusWidget::unfoldTreeList( bool persist )
893{
894 if( mFace == TreeList )
895 {
896 if( persist )
897 connect( mTreeList, SIGNAL( collapsed( QListViewItem * ) ), this, SLOT( slotReopen( QListViewItem * ) ) );
898 else
899 disconnect( mTreeList, SIGNAL( collapsed( QListViewItem * ) ), this, SLOT( slotReopen( QListViewItem * ) ) );
900
901 for( QListViewItem * item = mTreeList->firstChild(); item; item = item->itemBelow() )
902 item->setOpen( true );
903 }
904}
905
906void KJanusWidget::showEvent( QShowEvent * )
907{
908 if( mFace == TreeList )
909 {
910/*US
911 QSplitter *splitter = (QSplitter*)(mTreeList->parentWidget());
912 splitter->setResizeMode( mTreeList, mTreeListResizeMode );
913*/
914 }
915}
916
917
918//
919// 2000-13-02 Espen Sand
920// It should be obvious that this eventfilter must only be
921// be installed on the vertical scrollbar of the mIconList.
922//
923bool KJanusWidget::eventFilter( QObject *o, QEvent *e )
924{
925 if( e->type() == QEvent::Show )
926 {
927 IconListItem *item = (IconListItem*)mIconList->item(0);
928 if( item != 0 )
929 {
930 int lw = item->width( mIconList );
931 int sw = mIconList->verticalScrollBar()->sizeHint().width();
932 mIconList->setFixedWidth( lw+sw+mIconList->frameWidth()*2 );
933 }
934 }
935 else if( e->type() == QEvent::Hide )
936 {
937 IconListItem *item = (IconListItem*)mIconList->item(0);
938 if( item != 0 )
939 {
940 int lw = item->width( mIconList );
941 mIconList->setFixedWidth( lw+mIconList->frameWidth()*2 );
942 }
943 }
944 return QWidget::eventFilter( o, e );
945}
946
947
948
949//
950// Code for the icon list box
951//
952
953
954KJanusWidget::IconListBox::IconListBox( QWidget *parent, const char *name,
955 WFlags f )
956 :KListBox( parent, name, f ), mShowAll(false), mHeightValid(false),
957 mWidthValid(false)
958{
959}
960
961
962void KJanusWidget::IconListBox::updateMinimumHeight()
963{
964 if( mShowAll == true && mHeightValid == false )
965 {
966 int h = frameWidth()*2;
967 for( QListBoxItem *i = item(0); i != 0; i = i->next() )
968 {
969 h += i->height( this );
970 }
971 setMinimumHeight( h );
972 mHeightValid = true;
973 }
974}
975
976
977void KJanusWidget::IconListBox::updateWidth()
978{
979 if( mWidthValid == false )
980 {
981 int maxWidth = 10;
982 for( QListBoxItem *i = item(0); i != 0; i = i->next() )
983 {
984 int w = ((IconListItem *)i)->width(this);
985 maxWidth = QMAX( w, maxWidth );
986 }
987
988 for( QListBoxItem *i = item(0); i != 0; i = i->next() )
989 {
990 ((IconListItem *)i)->expandMinimumWidth( maxWidth );
991 }
992
993 if( verticalScrollBar()->isVisible() )
994 {
995 maxWidth += verticalScrollBar()->sizeHint().width();
996 }
997
998 setFixedWidth( maxWidth + frameWidth()*2 );
999 mWidthValid = true;
1000 }
1001}
1002
1003
1004void KJanusWidget::IconListBox::invalidateHeight()
1005{
1006 mHeightValid = false;
1007}
1008
1009
1010void KJanusWidget::IconListBox::invalidateWidth()
1011{
1012 mWidthValid = false;
1013}
1014
1015
1016void KJanusWidget::IconListBox::setShowAll( bool showAll )
1017{
1018 mShowAll = showAll;
1019 mHeightValid = false;
1020}
1021
1022
1023
1024KJanusWidget::IconListItem::IconListItem( QListBox *listbox, const QPixmap &pixmap,
1025 const QString &text )
1026 : QListBoxItem( listbox )
1027{
1028 mPixmap = pixmap;
1029 if( mPixmap.isNull() == true )
1030 {
1031 mPixmap = defaultPixmap();
1032 }
1033 setText( text );
1034 mMinimumWidth = 0;
1035}
1036
1037
1038int KJanusWidget::IconListItem::expandMinimumWidth( int width )
1039{
1040 mMinimumWidth = QMAX( mMinimumWidth, width );
1041 return( mMinimumWidth );
1042}
1043
1044
1045const QPixmap &KJanusWidget::IconListItem::defaultPixmap()
1046{
1047 static QPixmap *pix=0;
1048 if( pix == 0 )
1049 {
1050 pix = new QPixmap( 32, 32 );
1051 QPainter p( pix );
1052 p.eraseRect( 0, 0, pix->width(), pix->height() );
1053 p.setPen( Qt::red );
1054 p.drawRect ( 0, 0, pix->width(), pix->height() );
1055 p.end();
1056
1057 QBitmap mask( pix->width(), pix->height(), true);
1058 mask.fill( Qt::black );
1059 p.begin( &mask );
1060 p.setPen( Qt::white );
1061 p.drawRect ( 0, 0, pix->width(), pix->height() );
1062 p.end();
1063
1064 pix->setMask( mask );
1065 }
1066 return( *pix );
1067}
1068
1069
1070void KJanusWidget::IconListItem::paint( QPainter *painter )
1071{
1072 QFontMetrics fm = painter->fontMetrics();
1073 //int wt = fm.boundingRect(text()).width();
1074 int wp = mPixmap.width();
1075 int ht = fm.lineSpacing();
1076 int hp = mPixmap.height();
1077
1078 painter->drawPixmap( (mMinimumWidth-wp)/2, 5, mPixmap );
1079 if( text().isEmpty() == false )
1080 {
1081 painter->drawText( 0, hp+7, mMinimumWidth, ht, Qt::AlignCenter, text() );
1082 }
1083}
1084
1085int KJanusWidget::IconListItem::height( const QListBox *lb ) const
1086{
1087 if( text().isEmpty() == true )
1088 {
1089 return( mPixmap.height() );
1090 }
1091 else
1092 {
1093 return( mPixmap.height() + lb->fontMetrics().lineSpacing()+10 );
1094 }
1095}
1096
1097
1098int KJanusWidget::IconListItem::width( const QListBox *lb ) const
1099{
1100 int wt = lb->fontMetrics().boundingRect(text()).width()+10;
1101 int wp = mPixmap.width() + 10;
1102 int w = QMAX( wt, wp );
1103 return( QMAX( w, mMinimumWidth ) );
1104}
1105
1106
1107void KJanusWidget::virtual_hook( int, void* )
1108{ /*BASE::virtual_hook( id, data );*/ }
1109
1110// TODO: In TreeList, if the last child of a node is removed, and there is no corrsponding widget for that node, allow the caller to
1111// delete the node.
1112void KJanusWidget::removePage( QWidget *page )
1113{
1114//US qDebug("KJanusWidget::removePage 1 %lu , %lu, %lu", d, page, &(d->mPageToInt));
1115 if (!d || !(d->mPageToInt.contains(page)))
1116 {
1117 return;
1118 }
1119
1120 int index = d->mPageToInt[page];
1121
1122 if ( mFace == TreeList )
1123 {
1124 QMap<QListViewItem*, QWidget *>::Iterator i;
1125 for( i = mTreeListToPageStack.begin(); i != mTreeListToPageStack.end(); ++i )
1126 if (i.data()==page)
1127 {
1128 delete i.key();
1129 mPageStack->removeWidget(page);
1130 mTreeListToPageStack.remove(i);
1131 d->mIntToTitle.remove(index);
1132 d->mPageToInt.remove(page);
1133 d->mIntToPage.remove(index);
1134 break;
1135 }
1136 }
1137 else if ( mFace == IconList )
1138 {
1139 QMap<QListBoxItem*, QWidget *>::Iterator i;
1140 for( i = mIconListToPageStack.begin(); i != mIconListToPageStack.end(); ++i )
1141 if (i.data()==page)
1142 {
1143 delete i.key();
1144 mPageStack->removeWidget(page);
1145 mIconListToPageStack.remove(i);
1146 d->mIntToTitle.remove(index);
1147 d->mPageToInt.remove(page);
1148 d->mIntToPage.remove(index);
1149 break;
1150 }
1151 }
1152 else // Tabbed
1153 {
1154 mTabControl->removePage(page);
1155 d->mPageToInt.remove(page);
1156 d->mIntToPage.remove(index);
1157 }
1158}
1159
1160QString KJanusWidget::pageTitle(int index) const
1161{
1162 if (!d || !d->mIntToTitle.contains(index))
1163 return QString::null;
1164 else
1165 return d->mIntToTitle[index];
1166}
1167
1168QWidget *KJanusWidget::pageWidget(int index) const
1169{
1170 if (!d || !d->mIntToPage.contains(index))
1171 return 0;
1172 else
1173 return d->mIntToPage[index];
1174}
1175
1176//US #include "kjanuswidget.moc"
diff --git a/microkde/kdeui/kjanuswidget.h b/microkde/kdeui/kjanuswidget.h
new file mode 100644
index 0000000..6d3f23d
--- a/dev/null
+++ b/microkde/kdeui/kjanuswidget.h
@@ -0,0 +1,565 @@
1/* This file is part of the KDE Libraries
2 * Copyright (C) 1999-2000 Espen Sand (espen@kde.org)
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public License
15 * along with this library; see the file COPYING.LIB. If not, write to
16 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
18 */
19
20#ifndef _KJANUS_WIDGET_H_
21#define _KJANUS_WIDGET_H_
22
23#include <qptrlist.h>
24#include <qwidget.h>
25#include <qmap.h>
26#include <qgrid.h>
27#include <klistbox.h>
28
29/*US
30#include <qptrlist.h>
31#include <qpixmap.h>
32#include <qsplitter.h>
33
34#include <qstringlist.h>
35#include <qmap.h>
36
37*/
38
39class KSeparator;
40class KListView;
41class QWidgetStack;
42class QLabel;
43class QTabWidget;
44class QListViewItem;
45class QVBox;
46class QHBox;
47
48/**
49 * Provides a number of ready to use layouts (faces). It is used
50 * as an internal widget in @ref KDialogBase, but can also used as a
51 * widget of its own.
52 *
53 * It provides TreeList, IconList, Tabbed, Plain and Swallow layouts.
54 *
55 * The TreeList face provides a list in the left area and pages in the
56 * right. The area are separated by a movable splitter. The style is somewhat
57 * similar to the layout in the Control Center. A page is raised by
58 * selecting the corresponding tree list item.
59 *
60 * The IconList face provides an icon list in the left area and pages in the
61 * right. For each entry the Icon is on top with the text below. The style
62 * is somewhat similar to the layout of the Eudora configuation dialog box.
63 * A page is raised by selecting the corresponding icon list item. The
64 * preferred icon size is 32x32 pixels.
65 *
66 * The Tabbed face is a common tabbed widget. The procedure for creating a
67 * page is similar for creating a TreeList. This has the advantage that if
68 * your widget contain too many pages it is trivial to convert it into a
69 * TreeList. Just change the face in the KJanusWidget constructor to
70 * KJanusWidget::TreeList and you have a tree list layout instead.
71 *
72 * The Plain face provides an empty widget (QFrame) where you can place your
73 * widgets. The KJanusWidget makes no assumptions regarding the contents so
74 * you are free to add whatever you want.
75 *
76 * The Swallow face is provided in order to simplify the usage of existing
77 * widgets and to allow changing the visible widget. You specify the widget
78 * to be displayed by @ref #setSwallowedWidget(). Your widget will be
79 * reparented inside the widget. You can specify a Null (0) widget. A empty
80 * space is then displayed.
81 *
82 * For all modes it is important that you specify the @ref QWidget::minimumSize()
83 * on the page, plain widget or the swallowed widget. If you use a QLayout
84 * on the page, plain widget or the swallowed widget this will be taken care
85 * of automatically. The size is used when the KJanusWidget determines its
86 * own minimum size. You get the minimum size by using the
87 * @ref #minimumSizeHint() or @ref #sizeHint() methods.
88 *
89 * Pages that have been added in TreeList, IconList or Tabbed mode can be
90 * removed by simply deleting the page. However, it would be preferable to use
91 * the QObject::deleteLater() function on the page as the main event loop
92 * may have optimized UI update events of the page by scheduling them for later.
93 *
94 * @short Easy to use widget with many layouts
95 * @author Espen Sand (espen@kde.org)
96 */
97class KJanusWidget : public QWidget
98{
99 Q_OBJECT
100
101 private:
102 class IconListBox : public KListBox
103 {
104 public:
105 IconListBox( QWidget *parent=0, const char *name=0, WFlags f=0 );
106 void updateMinimumHeight();
107 void updateWidth();
108 void invalidateHeight();
109 void invalidateWidth();
110 void setShowAll( bool showAll );
111
112 private:
113 bool mShowAll;
114 bool mHeightValid;
115 bool mWidthValid;
116 };
117
118 public:
119 enum Face
120 {
121 TreeList = 0,
122 Tabbed,
123 Plain,
124 Swallow,
125 IconList
126 };
127
128 public:
129
130 /**
131 * Constructor where you specify the face.
132 *
133 * @param parent Parent of the widget.
134 * @param name Widget name.
135 * @param int face The kind of dialog, Use TreeList, Tabbed, Plain or
136 * Swallow.
137 */
138 KJanusWidget( QWidget *parent=0, const char *name=0, int face=Plain );
139
140 /**
141 * Destructor.
142 */
143 ~KJanusWidget();
144
145 /**
146 * Raises the page which was added by @ref addPage().
147 *
148 * @param index The index of the page you want to raise.
149 */
150 virtual bool showPage( int index );
151
152 /**
153 * Returns the index of the page that are currently displayed.
154 *
155 * @return The index or -1 if the face is not Tabbed, TreeList or
156 * IconList.
157 */
158 virtual int activePageIndex() const;
159
160 /**
161 * Use this to verify
162 * that no memory allocation failed.
163 *
164 * @return true if the widget was properly created.
165 */
166 virtual bool isValid() const;
167
168 /**
169 * Returns the face type.
170 *
171 * @return The face type.
172 */
173 virtual int face() const;
174
175 /**
176 * Returns the minimum size that must be made available for the widget
177 * so that UIs can be displayed properly
178 *
179 * @return The minimum size.
180 */
181 virtual QSize minimumSizeHint() const;
182
183 /**
184 * Returns the recommended size for the widget in order to be displayed
185 * properly.
186 *
187 * @return The recommended size.
188 */
189 virtual QSize sizeHint() const;
190
191 /**
192 * Returns the empty widget that is available in Plain mode.
193 *
194 * @return The widget or 0 if the face in not Plain.
195 */
196 virtual QFrame *plainPage();
197
198 /**
199 * Add a new page when the class is used in TreeList, IconList or Tabbed
200 * mode. The returned widget is empty and you must add your widgets
201 * as children to this widget. In most cases you must create a layout
202 * manager and associate it with this widget as well.
203 *
204 * Deleting the returned frame will cause the listitem or tab to be
205 * removed (you can re-add a page with the same name later.
206 *
207 * @param item String used in the list or Tab item.
208 * @param header A longer string used in TreeList and IconList mode to
209 * describe the contents of a page. If empty, the item string
210 * will be used instead.
211 * @param pixmap Used in IconList mode or in TreeList mode. You should
212 * prefer a pixmap with size 32x32 pixels.
213 *
214 * @return The empty page or 0 if the face is not TreeList, IconList or
215 * Tabbed.
216 */
217 virtual QFrame *addPage(const QString &item,const QString &header=QString::null,
218 const QPixmap &pixmap=QPixmap() );
219
220 /**
221 * This is like addPage just above, with the difference that the first
222 * element is a list of strings. These strings are used to form a path
223 * of folders down to the given page. The initial elements are names
224 * for the folders, while the last element is the name of the page.
225 * Note: This does yet only work for the TreeList face. Later this may
226 * be added for the IconList face too. In other faces than the
227 * TreeList, all the strings except the last one is ignored.
228 * Deleting the returned frame will cause the listitem or tab to be
229 * removed (you can re-add a page with the same name later.
230 *
231 * Deleting the returned frame will cause the listitem or tab to be
232 * removed (you can re-add a page with the same name later.
233 **/
234 virtual QFrame *addPage(const QStringList &items, const QString &header=QString::null,
235 const QPixmap &pixmap=QPixmap() );
236
237 /**
238 * Add a new page when the class is used in TreeList, IconList or Tabbed
239 * mode. The returned widget is empty and you must add your widgets
240 * as children to this widget. The returned widget is a @ref QVBox
241 * so it contains a QVBoxLayout layout that lines up the child widgets
242 * are vertically.
243 *
244 * Deleting the returned frame will cause the listitem or tab to be
245 * removed (you can re-add a page with the same name later.
246 *
247 * @param item String used in the list or Tab item.
248 * @param header A longer string used in TreeList and IconList mode to
249 * describe the contents of a page. If empty, the item string
250 * will be used instead.
251 * @param pixmap Used in IconList mode or in TreeList mode. You should
252 * prefer a pixmap with size 32x32 pixels.
253 *
254 * @return The empty page or 0 if the face is not TreeList, IconList or
255 * Tabbed. */
256 virtual QVBox *addVBoxPage( const QString &item,
257 const QString &header=QString::null,
258 const QPixmap &pixmap=QPixmap() );
259
260 /**
261 * This is like addVBoxPage just above, with the difference that the first
262 * element is a list of strings. These strings are used to form a path
263 * of folders down to the given page. The initial elements are names
264 * for the folders, while the last element is the name of the page.
265 * Note: This does yet only work for the TreeList face. Later this may
266 * be added for the IconList face too. In other faces than the
267 * TreeList, all the strings except the last one is ignored.
268 *
269 * Deleting the returned frame will cause the listitem or tab to be
270 * removed (you can re-add a page with the same name later.
271 **/
272 virtual QVBox *addVBoxPage( const QStringList &items,
273 const QString &header=QString::null,
274 const QPixmap &pixmap=QPixmap() );
275
276 /**
277 * Add a new page when the class is used in TreeList, IconList or Tabbed
278 * mode. The returned widget is empty and you must add your widgets
279 * as children to this widget. The returned widget is a @ref QHBox
280 * so it contains a QHBoxLayout layout that lines up the child widgets
281 * are horizontally.
282 *
283 * Deleting the returned frame will cause the listitem or tab to be
284 * removed (you can re-add a page with the same name later.
285 *
286 * @param item String used in the list or Tab item.
287 * @param header A longer string used in TreeList and IconList mode to
288 * describe the contents of a page. If empty, the item string
289 * will be used instead.
290 * @param pixmap Used in IconList mode or in TreeList mode. You should
291 * prefer a pixmap with size 32x32 pixels.
292 *
293 * @return The empty page or 0 if the face is not TreeList, IconList or
294 * Tabbed.
295 */
296 virtual QHBox *addHBoxPage( const QString &itemName,
297 const QString &header=QString::null,
298 const QPixmap &pixmap=QPixmap() );
299
300 /**
301 * This is like addHBoxPage just above, with the difference that the first
302 * element is a list of strings. These strings are used to form a path
303 * of folders down to the given page. The initial elements are names
304 * for the folders, while the last element is the name of the page.
305 * Note: This does yet only work for the TreeList face. Later this may
306 * be added for the IconList face too. In other faces than the
307 * TreeList, all the strings except the last one is ignored.
308 *
309 * Deleting the returned frame will cause the listitem or tab to be
310 * removed (you can re-add a page with the same name later.
311 **/
312 virtual QHBox *addHBoxPage( const QStringList &items,
313 const QString &header=QString::null,
314 const QPixmap &pixmap=QPixmap() );
315
316 /**
317 * Add a new page when the class is used in either TreeList or Tabbed
318 * mode. The returned widget is empty and you must add your widgets
319 * as children to this widget. The returned widget is a @ref QGrid
320 * so it contains a QGridLayout layout that places up the child widgets
321 * in a grid.
322 *
323 * Deleting the returned frame will cause the listitem or tab to be
324 * removed (you can re-add a page with the same name later.
325 *
326 * @param n Specifies the number of columns if 'dir' is QGrid::Horizontal
327 * or the number of rows if 'dir' is QGrid::Vertical.
328 * @param dir Can be QGrid::Horizontal or QGrid::Vertical.
329 * @param item String used in the list or Tab item.
330 * @param header A longer string used in TreeList and IconList mode to
331 * describe the contents of a page. If empty, the item string
332 * will be used instead.
333 * @param pixmap Used in IconList mode or in TreeList mode. You should
334 * prefer a pixmap with size 32x32 pixels.
335 *
336 * @return The empty page or 0 if the face is not TreeList, IconList or
337 * Tabbed.
338 */
339//US changed Orientation into Direction for compatibility
340 virtual QGrid *addGridPage( int n, QGrid::Direction dir,
341 const QString &itemName,
342 const QString &header=QString::null,
343 const QPixmap &pixmap=QPixmap() );
344
345 /**
346 * This is like addGridPage just above, with the difference that the first
347 * element is a list of strings. These strings are used to form a path
348 * of folders down to the given page. The initial elements are names
349 * for the folders, while the last element is the name of the page.
350 * Note: This does yet only work for the TreeList face. Later this may
351 * be added for the IconList face too. In other faces than the
352 * TreeList, all the strings except the last one is ignored.
353 *
354 * Deleting the returned frame will cause the listitem or tab to be
355 * removed (you can re-add a page with the same name later.
356 **/
357//US changed Orientation into Direction for compatibility
358 virtual QGrid *addGridPage( int n, QGrid::Direction dir,
359 const QStringList &items,
360 const QString &header=QString::null,
361 const QPixmap &pixmap=QPixmap() );
362
363 /**
364 * @short Removes a page created with @ref addPage, @ref addVBoxPage,
365 * @ref addHBoxPage or @ref addGridPage. If the page has already
366 * been deleted or has already been removed, nothing happens. The widget
367 * itself is not deleted.
368 *
369 * @param page The widget returned by @ref addPage , @ref addVBoxPage ,
370 * @ref addHBoxPage or @ref addGridPage .
371 */
372 void removePage( QWidget *page );
373
374
375 /**
376 * Returns the index of a page created with @ref addPage ,
377 * @ref addVBoxPage , @ref addHBoxPage or @ref addGridPage .
378 * You can can compare this index with the value returned from
379 * @ref activePageIndex if you need to do some page specific actions
380 * in your code.
381 *
382 * The returned index will never change so you can safely use this
383 * function once and save the value.
384 *
385 * @param widget The widget returned by @ref addPage , @ref addVBoxPage ,
386 * @ref addHBoxPage or @ref addGridPage .
387 *
388 * @return The index or -1 if the face is not Tabbed, TreeList or
389 * IconList
390 */
391 virtual int pageIndex( QWidget *widget ) const;
392
393 /**
394 * Defines the widget to be swallowed.
395 *
396 * This method can be used several
397 * times. Only the latest defined widget will be shown.
398 *
399 * @param widget The widget to be swallowed. If 0, then an empty rectangle
400 * is displayed.
401 */
402 virtual bool setSwallowedWidget( QWidget *widget );
403
404 /**
405 * This function has only effect in TreeList mode.
406 *
407 * Defines how the tree list is resized when the widget is resized
408 * horizontally. By default the tree list keeps its width when the
409 * widget becomes wider.
410 *
411 * @param state The resize mode. If false (default) the TreeList keeps
412 * its current width when the widget becomes wider.
413 */
414 virtual void setTreeListAutoResize( bool state );
415
416 /**
417 * This function has only effect in TreeList mode.
418 *
419 * This tells the widgets whether the icons given in the @ref addPage,
420 * @ref addVBoxPage, @ref addHBoxPage, or @ref addGridPage methods should
421 * be shown in the TreeList.
422 *
423 * Note: This method must be called before calling any of the methods
424 * which add icons to the page.
425 *
426 * @param state If true the icons are shown.
427 **/
428 virtual void setShowIconsInTreeList(bool state);
429
430 /**
431 * This function has only effect in TreeList mode.
432 *
433 * This tells the widgets whether the root should be decorated.
434 * For details see @ref QListView::setRootIsDecorated
435 *
436 * @param state Root will be decorated if true.
437 **/
438 virtual void setRootIsDecorated( bool state );
439
440 /**
441 * This function has only effect in TreeList mode.
442 *
443 * This tells the TreeList to unfold the whole tree so that all entries
444 * are visible.
445 *
446 * If the list is empty when you call this method newly created entries
447 * will not automatically be opened. If the @p persist flag is set opened
448 * entries cannot be closed again, though.
449 *
450 * @param persist If true the tree always stays unfolded.
451 * @since 3.2
452 */
453 /*virtual*/ void unfoldTreeList( bool persist = false ); //### KDE4 BIC add virtual
454
455 /**
456 * This function has only effect in IconList mode.
457 *
458 * Defines how the icon list widget is displayed. By default it is
459 * the widgets in the pages that decide the minimum height
460 * of the toplevel widget. A vertical scrollbar can be used in
461 * the icon list area.
462 *
463 * @param state The visibility mode. If true, the minimum height is
464 * adjusted so that every icon in the list is visible at the
465 * same time. The vertical scrollbar will never be visible.
466 */
467 virtual void setIconListAllVisible( bool state );
468
469 /**
470 * Sets the icon used in TreeList Mode for the given path.
471 * @param path The path for which this icon should be shown.
472 * @param pixmap The icon used.
473 **/
474 virtual void setFolderIcon(const QStringList &path, const QPixmap &pixmap);
475 /**
476 * Returns the title string associated with a page index in TreeList or IconList mode.
477 * @param index The index of the page or null if there is no such page.
478 * @see @ref #pageIndex()
479 * @since 3.2
480 */
481 /*virtual*/ QString pageTitle(int index) const;
482 /**
483 * Returns the page widget associated with a page index or null if there is
484 * no such page.
485 * @param index The index of the page.
486 * @see @ref #pageIndex()
487 * @since 3.2
488 */
489 /*virtual*/ QWidget *pageWidget(int index) const;
490
491 signals:
492 void aboutToShowPage(QWidget *page);
493
494 public slots:
495 /**
496 * Give the keyboard input focus to the widget.
497 */
498 virtual void setFocus();
499
500 protected:
501 /**
502 * Reimplemented to handle the splitter width when the the face
503 * is TreeList
504 */
505 virtual void showEvent( QShowEvent * );
506
507 /**
508 * This function is used internally when in IconList mode. If you
509 * reimplement this class a make your own event filter, make sure to
510 * call this function from your filter.
511 *
512 * @param o Object that has received an event.
513 * @param e The event.
514 */
515 virtual bool eventFilter( QObject *o, QEvent *e );
516
517 private slots:
518 bool slotShowPage();
519//US not yet implemented void slotFontChanged();
520 void slotItemClicked(QListViewItem *it);
521 void pageGone( QObject *obj); // signal from the added page's "destroyed" signal
522 void slotReopen(QListViewItem *item);
523
524 protected:
525 bool showPage( QWidget *w );
526 void addPageWidget( QFrame *page, const QStringList &items,
527 const QString &header, const QPixmap &pixmap );
528 void InsertTreeListItem(const QStringList &items, const QPixmap &pixmap, QFrame *page);
529 QWidget *FindParent();
530
531 private:
532 bool mValid;
533
534 // Obsolete members. Remove in KDE 4.
535 QPtrList<QWidget> *mPageList;
536 QStringList *mTitleList;
537
538 int mFace;
539 KListView *mTreeList;
540 IconListBox *mIconList;
541 QWidgetStack *mPageStack;
542 QLabel *mTitleLabel;
543 QTabWidget *mTabControl;
544 QFrame *mPlainPage;
545 QWidget *mSwallowPage;
546 QWidget *mActivePageWidget;
547 KSeparator *mTitleSep;
548//US QSplitter::ResizeMode mTreeListResizeMode;
549 bool mShowIconsInTreeList;
550 QMap<QListViewItem *, QWidget *> mTreeListToPageStack;
551 QMap<QListBoxItem *, QWidget *> mIconListToPageStack;
552 QMap<QString, QPixmap> mFolderIconMap;
553 QMap<QString, QStringList> mChildrenNames;
554 QMap<QString, QWidget *> mChildPages;
555
556 public:
557 class IconListItem;
558 protected:
559 virtual void virtual_hook( int id, void* data );
560 private:
561 class KJanusWidgetPrivate;
562 KJanusWidgetPrivate *d;
563};
564
565#endif
diff --git a/microkde/kdeui/klistbox.cpp b/microkde/kdeui/klistbox.cpp
new file mode 100644
index 0000000..c65b892
--- a/dev/null
+++ b/microkde/kdeui/klistbox.cpp
@@ -0,0 +1,314 @@
1/* This file is part of the KDE libraries
2 Copyright (C) 2000 Reginald Stadlbauer <reggie@kde.org>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License version 2 as published by the Free Software Foundation.
7
8 This library is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 Library General Public License for more details.
12
13 You should have received a copy of the GNU Library General Public License
14 along with this library; see the file COPYING.LIB. If not, write to
15 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16 Boston, MA 02111-1307, USA.
17*/
18#include <qtimer.h>
19
20#include <kglobalsettings.h>
21//US#include <kcursor.h>
22#include <kapplication.h>
23//US#include <kipc.h>
24#include <kdebug.h>
25
26#include "klistbox.h"
27
28#ifdef Q_WS_X11
29#include <X11/Xlib.h>
30#endif
31#ifdef _WIN32_
32#define Q_WS_QWS
33#endif
34KListBox::KListBox( QWidget *parent, const char *name, WFlags f )
35 : QListBox( parent, name, f )
36{
37 connect( this, SIGNAL( onViewport() ),
38 this, SLOT( slotOnViewport() ) );
39 connect( this, SIGNAL( onItem( QListBoxItem * ) ),
40 this, SLOT( slotOnItem( QListBoxItem * ) ) );
41
42 connect( this, SIGNAL( mouseButtonClicked( int, QListBoxItem *,
43 const QPoint & ) ),
44 this, SLOT( slotMouseButtonClicked( int, QListBoxItem *,
45 const QPoint & ) ) );
46/*US
47
48 slotSettingsChanged(KApplication::SETTINGS_MOUSE);
49 if (kapp)
50 {
51 connect( kapp, SIGNAL( settingsChanged(int) ), SLOT( slotSettingsChanged(int) ) );
52 kapp->addKipcEventMask( KIPC::SettingsChanged );
53 }
54*/
55 m_pCurrentItem = 0L;
56//US set single to true
57 m_bUseSingle = true;
58 m_pAutoSelect = new QTimer( this );
59 connect( m_pAutoSelect, SIGNAL( timeout() ),
60 this, SLOT( slotAutoSelect() ) );
61}
62
63void KListBox::slotOnItem( QListBoxItem *item )
64{
65/*US
66 if ( item && m_bChangeCursorOverItem && m_bUseSingle )
67 viewport()->setCursor( KCursor().handCursor() );
68*/
69 if ( item && (m_autoSelectDelay > -1) && m_bUseSingle ) {
70 m_pAutoSelect->start( m_autoSelectDelay, true );
71 m_pCurrentItem = item;
72 }
73}
74
75void KListBox::slotOnViewport()
76{
77/*US
78 if ( m_bChangeCursorOverItem )
79 viewport()->unsetCursor();
80*/
81 m_pAutoSelect->stop();
82 m_pCurrentItem = 0L;
83}
84
85
86/*US
87void KListBox::slotSettingsChanged(int category)
88{
89 if (category != KApplication::SETTINGS_MOUSE)
90 return;
91
92 m_bUseSingle = KGlobalSettings::singleClick();
93 m_bUseSingle = true;
94
95 disconnect( this, SIGNAL( mouseButtonClicked( int, QListBoxItem *,
96 const QPoint & ) ),
97 this, SLOT( slotMouseButtonClicked( int, QListBoxItem *,
98 const QPoint & ) ) );
99// disconnect( this, SIGNAL( doubleClicked( QListBoxItem *,
100 // const QPoint & ) ),
101 // this, SLOT( slotExecute( QListBoxItem *,
102 // const QPoint & ) ) );
103
104 if( m_bUseSingle )
105 {
106 connect( this, SIGNAL( mouseButtonClicked( int, QListBoxItem *,
107 const QPoint & ) ),
108 this, SLOT( slotMouseButtonClicked( int, QListBoxItem *,
109 const QPoint & ) ) );
110 }
111 else
112 {
113// connect( this, SIGNAL( doubleClicked( QListBoxItem *,
114 // const QPoint & ) ),
115// this, SLOT( slotExecute( QListBoxItem *,
116 // const QPoint & ) ) );
117 }
118
119 m_bChangeCursorOverItem = KGlobalSettings::changeCursorOverIcon();
120 m_autoSelectDelay = KGlobalSettings::autoSelectDelay();
121
122 if( !m_bUseSingle || !m_bChangeCursorOverItem )
123 viewport()->unsetCursor();
124
125}
126*/
127void KListBox::slotAutoSelect()
128{
129 // check that the item still exists
130 if( index( m_pCurrentItem ) == -1 )
131 return;
132
133 //Give this widget the keyboard focus.
134 if( !hasFocus() )
135 setFocus();
136
137#ifdef Q_WS_X11 //FIXME
138 Window root;
139 Window child;
140 int root_x, root_y, win_x, win_y;
141 uint keybstate;
142 XQueryPointer( qt_xdisplay(), qt_xrootwin(), &root, &child,
143 &root_x, &root_y, &win_x, &win_y, &keybstate );
144#endif
145
146 QListBoxItem* previousItem = item( currentItem() );
147 setCurrentItem( m_pCurrentItem );
148
149 if( m_pCurrentItem ) {
150#ifndef Q_WS_QWS //FIXME
151 //Shift pressed?
152 if( (keybstate & ShiftMask) ) {
153#endif
154 bool block = signalsBlocked();
155 blockSignals( true );
156
157#ifndef Q_WS_QWS //FIXME
158 //No Ctrl? Then clear before!
159 if( !(keybstate & ControlMask) )
160 clearSelection();
161#endif
162
163//US in my QT version it is called isSelected() So what is right?
164//US bool select = !m_pCurrentItem->isSelected();
165 bool select = !m_pCurrentItem->selected();
166 bool update = viewport()->isUpdatesEnabled();
167 viewport()->setUpdatesEnabled( false );
168
169 bool down = index( previousItem ) < index( m_pCurrentItem );
170 QListBoxItem* it = down ? previousItem : m_pCurrentItem;
171 for (;it ; it = it->next() ) {
172 if ( down && it == m_pCurrentItem ) {
173 setSelected( m_pCurrentItem, select );
174 break;
175 }
176 if ( !down && it == previousItem ) {
177 setSelected( previousItem, select );
178 break;
179 }
180 setSelected( it, select );
181 }
182
183 blockSignals( block );
184 viewport()->setUpdatesEnabled( update );
185 triggerUpdate( false );
186
187 emit selectionChanged();
188
189 if( selectionMode() == QListBox::Single )
190 emit selectionChanged( m_pCurrentItem );
191 }
192#ifndef Q_WS_QWS //FIXME
193 else if( (keybstate & ControlMask) )
194 setSelected( m_pCurrentItem, !m_pCurrentItem->isSelected() );
195#endif
196 else {
197 bool block = signalsBlocked();
198 blockSignals( true );
199
200//US in my QT version it is called isSelected() So what is right?
201//US if( !m_pCurrentItem->isSelected() )
202 if( !m_pCurrentItem->selected() )
203 clearSelection();
204
205 blockSignals( block );
206
207 setSelected( m_pCurrentItem, true );
208 }
209#ifndef Q_WS_QWS //FIXME
210 }
211 else
212 kdDebug() << "Thats not supposed to happen!!!!" << endl;
213#endif
214}
215
216void KListBox::emitExecute( QListBoxItem *item, const QPoint &pos )
217{
218#ifdef Q_WS_X11 //FIXME
219 Window root;
220 Window child;
221 int root_x, root_y, win_x, win_y;
222 uint keybstate;
223 XQueryPointer( qt_xdisplay(), qt_xrootwin(), &root, &child,
224 &root_x, &root_y, &win_x, &win_y, &keybstate );
225#endif
226
227 m_pAutoSelect->stop();
228
229#ifndef Q_WS_QWS //FIXME
230 //Dont emit executed if in SC mode and Shift or Ctrl are pressed
231 if( !( m_bUseSingle && ((keybstate & ShiftMask) || (keybstate & ControlMask)) ) ) {
232#endif
233 emit executed( item );
234 emit executed( item, pos );
235#ifndef Q_WS_QWS //FIXME
236 }
237#endif
238}
239
240//
241// 2000-16-01 Espen Sand
242// This widget is used in dialogs. It should ignore
243// F1 (and combinations) and Escape since these are used
244// to start help or close the dialog. This functionality
245// should be done in QListView but it is not (at least now)
246//
247void KListBox::keyPressEvent(QKeyEvent *e)
248{
249 if( e->key() == Key_Escape )
250 {
251 e->ignore();
252 }
253 else if( e->key() == Key_F1 )
254 {
255 e->ignore();
256 }
257 else
258 {
259 QListBox::keyPressEvent(e);
260 }
261}
262
263void KListBox::focusOutEvent( QFocusEvent *fe )
264{
265 m_pAutoSelect->stop();
266
267 QListBox::focusOutEvent( fe );
268}
269
270void KListBox::leaveEvent( QEvent *e )
271{
272 m_pAutoSelect->stop();
273
274 QListBox::leaveEvent( e );
275}
276
277void KListBox::contentsMousePressEvent( QMouseEvent *e )
278{
279 if( (selectionMode() == Extended) && (e->state() & ShiftButton) && !(e->state() & ControlButton) ) {
280 bool block = signalsBlocked();
281 blockSignals( true );
282
283 clearSelection();
284
285 blockSignals( block );
286 }
287
288 QListBox::contentsMousePressEvent( e );
289}
290
291void KListBox::contentsMouseDoubleClickEvent ( QMouseEvent * e )
292{
293 QListBox::contentsMouseDoubleClickEvent( e );
294
295 QListBoxItem* item = itemAt( e->pos() );
296
297 if( item ) {
298 emit doubleClicked( item, e->globalPos() );
299
300 if( (e->button() == LeftButton) && !m_bUseSingle )
301 emitExecute( item, e->globalPos() );
302 }
303}
304
305void KListBox::slotMouseButtonClicked( int btn, QListBoxItem *item, const QPoint &pos )
306{
307 if( (btn == LeftButton) && item )
308 emitExecute( item, pos );
309}
310
311void KListBox::virtual_hook( int, void* )
312{ /*BASE::virtual_hook( id, data );*/ }
313
314//US #include "klistbox.moc"
diff --git a/microkde/kdeui/klistbox.h b/microkde/kdeui/klistbox.h
new file mode 100644
index 0000000..8023780
--- a/dev/null
+++ b/microkde/kdeui/klistbox.h
@@ -0,0 +1,141 @@
1/* This file is part of the KDE libraries
2 Copyright (C) 2000 Reginald Stadlbauer <reggie@kde.org>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License version 2 as published by the Free Software Foundation.
7
8 This library is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 Library General Public License for more details.
12
13 You should have received a copy of the GNU Library General Public License
14 along with this library; see the file COPYING.LIB. If not, write to
15 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16 Boston, MA 02111-1307, USA.
17*/
18#ifndef KLISTBOX_H
19#define KLISTBOX_H
20
21#include <qlistbox.h>
22
23/**
24 * Extends the functionality of @ref QListBox to honor the system
25 * wide settings for Single Click/Double Click mode, Auto Selection and
26 * Change Cursor over Link.
27 *
28 * There is a new signal @ref executed(). It gets connected to either
29 * @ref QListBox::clicked() or @ref QListBox::doubleClicked()
30 * depending on the KDE wide Single Click/Double Click settings. It is
31 * strongly recomended that you use this signal instead of the above
32 * mentioned. This way you don't need to care about the current
33 * settings. If you want to get informed when the user selects
34 * something connect to the @ref QListBox::selectionChanged() signal.
35 *
36 * @short A variant of @ref QListBox that honors KDE's system-wide settings.
37 **/
38class KListBox : public QListBox
39{
40 Q_OBJECT
41
42public:
43 KListBox( QWidget *parent = 0, const char *name = 0, WFlags f = 0 );
44
45signals:
46
47 /**
48 * Emitted whenever the user executes an listbox item.
49 *
50 * That means depending on the KDE wide Single Click/Double Click
51 * setting the user clicked or double clicked on that item.
52 * @param item is the pointer to the executed listbox item.
53 *
54 * Note that you may not delete any @ref QListBoxItem objects in slots
55 * connected to this signal.
56 */
57 void executed( QListBoxItem *item );
58
59 /**
60 * Emitted whenever the user executes an listbox item.
61 *
62 * That means depending on the KDE wide Single Click/Double Click
63 * setting the user clicked or double clicked on that item.
64 * @param item is the pointer to the executed listbox item.
65 * @param pos is the position where the user has clicked
66 *
67 * Note that you may not delete any @ref QListBoxItem objects in slots
68 * connected to this signal.
69 */
70 void executed( QListBoxItem *item, const QPoint &pos );
71
72 /**
73 * This signal gets emitted whenever the user double clicks into the
74 * listbox.
75 *
76 * @param item The pointer to the clicked listbox item.
77 * @param pos The position where the user has clicked.
78 *
79 * Note that you may not delete any @ref QListBoxItem objects in slots
80 * connected to this signal.
81 *
82 * This signal is more or less here for the sake of completeness.
83 * You should normally not need to use this. In most cases it's better
84 * to use @ref executed() instead.
85 */
86 void doubleClicked( QListBoxItem *item, const QPoint &pos );
87
88protected slots:
89 void slotOnItem( QListBoxItem *item );
90 void slotOnViewport();
91
92//US void slotSettingsChanged(int);
93
94 /**
95 * Auto selection happend.
96 */
97 void slotAutoSelect();
98
99protected:
100 void emitExecute( QListBoxItem *item, const QPoint &pos );
101
102 /**
103 * @reimplemented
104 */
105 virtual void keyPressEvent(QKeyEvent *e);
106 /**
107 * @reimplemented
108 */
109 virtual void focusOutEvent( QFocusEvent *fe );
110 /**
111 * @reimplemented
112 */
113 virtual void leaveEvent( QEvent *e );
114 /**
115 * @reimplemented
116 */
117 virtual void contentsMousePressEvent( QMouseEvent *e );
118 /**
119 * @reimplemented
120 */
121 virtual void contentsMouseDoubleClickEvent ( QMouseEvent *e );
122
123 bool m_bUseSingle;
124//US bool m_bChangeCursorOverItem;
125
126 QListBoxItem* m_pCurrentItem;
127
128 QTimer* m_pAutoSelect;
129 int m_autoSelectDelay;
130
131private slots:
132 void slotMouseButtonClicked( int btn, QListBoxItem *item, const QPoint &pos );
133
134protected:
135 virtual void virtual_hook( int id, void* data );
136private:
137 class KListBoxPrivate;
138 KListBoxPrivate *d;
139};
140
141#endif
diff --git a/microkde/kdeui/klistview.cpp b/microkde/kdeui/klistview.cpp
new file mode 100644
index 0000000..b53a88a
--- a/dev/null
+++ b/microkde/kdeui/klistview.cpp
@@ -0,0 +1,2191 @@
1/* This file is part of the KDE libraries
2 Copyright (C) 2000 Reginald Stadlbauer <reggie@kde.org>
3 Copyright (C) 2000 Charles Samuels <charles@kde.org>
4 Copyright (C) 2000 Peter Putzer
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License version 2 as published by the Free Software Foundation.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21#include <qdragobject.h>
22#include <qtimer.h>
23#include <qheader.h>
24#include <qcursor.h>
25#include <qtooltip.h>
26#include <qstyle.h>
27#include <qpainter.h>
28
29#include <kglobalsettings.h>
30#include <kconfig.h>
31#include <kconfigbase.h>
32//US #include <kcursor.h>
33#include <kapplication.h>
34//US #include <kipc.h>
35#include <kdebug.h>
36#ifdef _WIN32_
37#define Q_WS_QWS
38#endif
39#ifndef _WIN32_
40#define private public
41#include <qlistview.h>
42#undef private
43#endif
44#include "klistview.h"
45//US #include "klistviewlineedit.h"
46#ifndef DESKTOP_VERSION
47#include <qpe/qpeapplication.h>
48#endif
49
50// /*US
51class KListView::Tooltip : public QToolTip
52{
53public:
54 Tooltip (KListView* parent, QToolTipGroup* group = 0L);
55 virtual ~Tooltip () {}
56
57protected:
58 // */
59 /**
60 * Reimplemented from QToolTip for internal reasons.
61 */
62 // /*US
63 virtual void maybeTip (const QPoint&);
64
65private:
66 KListView* mParent;
67};
68
69KListView::Tooltip::Tooltip (KListView* parent, QToolTipGroup* group)
70 : QToolTip (parent, group),
71 mParent (parent)
72{
73}
74
75void KListView::Tooltip::maybeTip (const QPoint&)
76{
77 // FIXME
78}
79// */
80
81class KListView::KListViewPrivate
82{
83public:
84 KListViewPrivate (KListView* listview)
85 : pCurrentItem (0L),
86 autoSelectDelay(1),
87//US dragDelay (KGlobalSettings::dndEventDelay()),
88
89 dragDelay (10),
90//US editor (new KListViewLineEdit (listview)),
91 cursorInExecuteArea(false),
92 bUseSingle(false),
93 bChangeCursorOverItem(false),
94 itemsMovable (true),
95 selectedBySimpleMove(false),
96 selectedUsingMouse(false),
97 showContextMenusOnPress(true),
98 itemsRenameable (false),
99 validDrag (false),
100 dragEnabled (false),
101 autoOpen (true),
102 dropVisualizer (true),
103 dropHighlighter (false),
104 createChildren (true),
105 pressedOnSelected (false),
106 wasShiftEvent (false),
107 fullWidth (false),
108 sortAscending(true),
109 tabRename(true),
110 sortColumn(0),
111 selectionDirection(0),
112 tooltipColumn (0),
113 selectionMode (Single),
114//US contextMenuKey (KGlobalSettings::contextMenuKey()),
115//US showContextMenusOnPress (KGlobalSettings::showContextMenusOnPress()),
116 mDropVisualizerWidth (4)
117 {
118 renameable += 0;
119//US connect(editor, SIGNAL(done(QListViewItem*,int)), listview, SLOT(doneEditing(QListViewItem*,int)));
120 }
121
122 ~KListViewPrivate ()
123 {
124//US delete editor;
125 }
126
127 QListViewItem* pCurrentItem;
128
129 QTimer autoSelect;
130 int autoSelectDelay;
131
132 QTimer dragExpand;
133 QListViewItem* dragOverItem;
134 QPoint dragOverPoint;
135
136 QPoint startDragPos;
137 int dragDelay;
138
139//US KListViewLineEdit *editor;
140 QValueList<int> renameable;
141
142 bool cursorInExecuteArea:1;
143 bool bUseSingle:1;
144 bool bChangeCursorOverItem:1;
145 bool itemsMovable:1;
146 bool selectedBySimpleMove : 1;
147 bool selectedUsingMouse:1;
148 bool itemsRenameable:1;
149 bool validDrag:1;
150 bool dragEnabled:1;
151 bool autoOpen:1;
152 bool dropVisualizer:1;
153 bool dropHighlighter:1;
154 bool createChildren:1;
155 bool pressedOnSelected:1;
156 bool wasShiftEvent:1;
157 bool fullWidth:1;
158 bool sortAscending:1;
159 bool tabRename:1;
160
161 int sortColumn;
162
163 //+1 means downwards (y increases, -1 means upwards, 0 means not selected), aleXXX
164 int selectionDirection;
165 int tooltipColumn;
166
167 SelectionModeExt selectionMode;
168 int contextMenuKey;
169 bool showContextMenusOnPress;
170
171 QRect mOldDropVisualizer;
172 int mDropVisualizerWidth;
173 QRect mOldDropHighlighter;
174 QListViewItem *afterItemDrop;
175 QListViewItem *parentItemDrop;
176
177 QColor alternateBackground;
178};
179
180/*US
181KListViewLineEdit::KListViewLineEdit(KListView *parent)
182 : KLineEdit(parent->viewport()), item(0), col(0), p(parent)
183{
184 setFrame( false );
185 hide();
186 connect( parent, SIGNAL( selectionChanged() ), SLOT( slotSelectionChanged() ));
187}
188
189KListViewLineEdit::~KListViewLineEdit()
190{
191}
192
193void KListViewLineEdit::load(QListViewItem *i, int c)
194{
195 item=i;
196 col=c;
197
198 QRect rect(p->itemRect(i));
199 setText(item->text(c));
200
201 int fieldX = rect.x() - 1;
202 int fieldW = p->columnWidth(col) + 2;
203
204 int pos = p->header()->mapToIndex(col);
205 for ( int index = 0; index < pos; index++ )
206 fieldX += p->columnWidth( p->header()->mapToSection( index ));
207
208 if ( col == 0 ) {
209 int d = i->depth() + (p->rootIsDecorated() ? 1 : 0);
210 d *= p->treeStepSize();
211 fieldX += d;
212 fieldW -= d;
213 }
214
215 if ( i->pixmap( col ) ) {// add width of pixmap
216 int d = i->pixmap( col )->width();
217 fieldX += d;
218 fieldW -= d;
219 }
220
221 setGeometry(fieldX, rect.y() - 1, fieldW, rect.height() + 2);
222 show();
223 setFocus();
224}
225*/
226 /*Helper functions to for
227 *tabOrderedRename functionality.
228 */
229
230static int nextCol (KListView *pl, QListViewItem *pi, int start, int dir)
231{
232 if (pi)
233 {
234 //Find the next renameable column in the current row
235 for (; ((dir == +1) ? (start < pl->columns()) : (start >= 0)); start += dir)
236 if (pl->isRenameable(start))
237 return start;
238 }
239
240 return -1;
241}
242
243static QListViewItem *prevItem (QListViewItem *pi)
244{
245 QListViewItem *pa = pi->itemAbove();
246
247 /*Does what the QListViewItem::previousSibling()
248 *of my dreams would do.
249 */
250 if (pa && pa->parent() == pi->parent())
251 return pa;
252
253 return NULL;
254}
255
256static QListViewItem *lastQChild (QListViewItem *pi)
257{
258 if (pi)
259 {
260 /*Since there's no QListViewItem::lastChild().
261 *This finds the last sibling for the given
262 *item.
263 */
264 for (QListViewItem *pt = pi->nextSibling(); pt; pt = pt->nextSibling())
265 pi = pt;
266 }
267
268 return pi;
269}
270/*US
271void KListViewLineEdit::selectNextCell (QListViewItem *pitem, int column, bool forward)
272{
273 const int ncols = p->columns();
274 const int dir = forward ? +1 : -1;
275 const int restart = forward ? 0 : (ncols - 1);
276 QListViewItem *top = (pitem && pitem->parent())
277 ? pitem->parent()->firstChild()
278 : p->firstChild();
279 QListViewItem *pi = pitem;
280
281 terminate(); //Save current changes
282
283 do
284 {
285*/
286 /*Check the rest of the current row for an editable column,
287 *if that fails, check the entire next/previous row. The
288 *last case goes back to the first item in the current branch
289 *or the last item in the current branch depending on the
290 *direction.
291 */
292/*US
293 if ((column = nextCol(p, pi, column + dir, dir)) != -1 ||
294 (column = nextCol(p, (pi = (forward ? pi->nextSibling() : prevItem(pi))), restart, dir)) != -1 ||
295 (column = nextCol(p, (pi = (forward ? top : lastQChild(pitem))), restart, dir)) != -1)
296 {
297 if (pi)
298 {
299 p->setCurrentItem(pi); //Calls terminate
300 p->rename(pi, column);
301*/
302 /*Some listviews may override rename() to
303 *prevent certain items from being renamed,
304 *if this is done, [m_]item will be NULL
305 *after the rename() call... try again.
306 */
307/*US
308 if (!item)
309 continue;
310
311 break;
312 }
313 }
314 }
315 while (pi && !item);
316}
317*/
318
319/*US
320#ifdef KeyPress
321#undef KeyPress
322#endif
323
324bool KListViewLineEdit::event (QEvent *pe)
325{
326 if (pe->type() == QEvent::KeyPress)
327 {
328 QKeyEvent *k = (QKeyEvent *) pe;
329
330 if ((k->key() == Qt::Key_Backtab || k->key() == Qt::Key_Tab) &&
331 p->tabOrderedRenaming() && p->itemsRenameable() &&
332 !(k->state() & ControlButton || k->state() & AltButton))
333 {
334 selectNextCell(item, col,
335 (k->key() == Key_Tab && !(k->state() & ShiftButton)));
336 return true;
337 }
338 }
339
340 return KLineEdit::event(pe);
341}
342
343void KListViewLineEdit::keyPressEvent(QKeyEvent *e)
344{
345 if(e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter )
346 terminate(true);
347 else if(e->key() == Qt::Key_Escape)
348 terminate(false);
349 else if (e->key() == Qt::Key_Down || e->key() == Qt::Key_Up)
350 {
351 terminate(true);
352 KLineEdit::keyPressEvent(e);
353 }
354 else
355 KLineEdit::keyPressEvent(e);
356}
357
358void KListViewLineEdit::terminate()
359{
360 terminate(true);
361}
362
363void KListViewLineEdit::terminate(bool commit)
364{
365 if ( item )
366 {
367 //kdDebug() << "KListViewLineEdit::terminate " << commit << endl;
368 if (commit)
369 item->setText(col, text());
370 int c=col;
371 QListViewItem *i=item;
372 col=0;
373 item=0;
374 hide(); // will call focusOutEvent, that's why we set item=0 before
375 emit done(i,c);
376 }
377}
378
379void KListViewLineEdit::focusOutEvent(QFocusEvent *ev)
380{
381 QFocusEvent * focusEv = static_cast<QFocusEvent*>(ev);
382 // Don't let a RMB close the editor
383 if (focusEv->reason() != QFocusEvent::Popup && focusEv->reason() != QFocusEvent::ActiveWindow)
384 terminate(true);
385}
386
387void KListViewLineEdit::paintEvent( QPaintEvent *e )
388{
389 KLineEdit::paintEvent( e );
390
391 if ( !frame() ) {
392 QPainter p( this );
393 p.setClipRegion( e->region() );
394 p.drawRect( rect() );
395 }
396}
397
398// selection changed -> terminate. As our "item" can be already deleted,
399// we can't call terminate(false), because that would emit done() with
400// a dangling pointer to "item".
401void KListViewLineEdit::slotSelectionChanged()
402{
403 item = 0;
404 col = 0;
405 hide();
406}
407*/
408
409KListView::KListView( QWidget *parent, const char *name )
410 : QListView( parent, name ),
411 d (new KListViewPrivate (this))
412{
413#ifndef DESKTOP_VERSION
414 QPEApplication::setStylusOperation( viewport(), QPEApplication::RightOnHold );
415#endif
416//US setDragAutoScroll(true);
417
418 connect( this, SIGNAL( onViewport() ),
419 this, SLOT( slotOnViewport() ) );
420 connect( this, SIGNAL( onItem( QListViewItem * ) ),
421 this, SLOT( slotOnItem( QListViewItem * ) ) );
422
423 connect (this, SIGNAL(contentsMoving(int,int)),
424 this, SLOT(cleanDropVisualizer()));
425 connect (this, SIGNAL(contentsMoving(int,int)),
426 this, SLOT(cleanItemHighlighter()));
427
428/*US
429 slotSettingsChanged(KApplication::SETTINGS_MOUSE);
430
431 if (kapp)
432 {
433 connect( kapp, SIGNAL( settingsChanged(int) ), SLOT( slotSettingsChanged(int) ) );
434 kapp->addKipcEventMask( KIPC::SettingsChanged );
435 }
436*/
437 slotSettingsChanged(1); //US do this to initialize the connections
438
439
440 connect(&d->autoSelect, SIGNAL( timeout() ),
441 this, SLOT( slotAutoSelect() ) );
442 connect(&d->dragExpand, SIGNAL( timeout() ),
443 this, SLOT( slotDragExpand() ) );
444
445 // context menu handling
446 if (d->showContextMenusOnPress)
447 {
448 connect (this, SIGNAL (rightButtonPressed (QListViewItem*, const QPoint&, int)),
449 this, SLOT (emitContextMenu (QListViewItem*, const QPoint&, int)));
450 }
451 else
452 {
453 connect (this, SIGNAL (rightButtonClicked (QListViewItem*, const QPoint&, int)),
454 this, SLOT (emitContextMenu (QListViewItem*, const QPoint&, int)));
455 }
456
457 connect (this, SIGNAL (menuShortCutPressed (KListView*, QListViewItem*)),
458 this, SLOT (emitContextMenu (KListView*, QListViewItem*)));
459
460
461 //qDebug("KListView::KListView make alternate color configurable");
462//US d->alternateBackground = KGlobalSettings::alternateBackgroundColor();
463 d->alternateBackground = QColor(240, 240, 240);
464}
465
466
467
468KListView::~KListView()
469{
470 delete d;
471}
472
473bool KListView::isExecuteArea( const QPoint& point )
474{
475 if ( itemAt( point ) )
476 return isExecuteArea( point.x() );
477
478 return false;
479}
480
481bool KListView::isExecuteArea( int x )
482{
483 if( allColumnsShowFocus() )
484 return true;
485 else {
486 int offset = 0;
487 int width = columnWidth( 0 );
488 int pos = header()->mapToIndex( 0 );
489
490 for ( int index = 0; index < pos; index++ )
491 offset += columnWidth( header()->mapToSection( index ) );
492
493 x += contentsX(); // in case of a horizontal scrollbar
494 return ( x > offset && x < ( offset + width ) );
495 }
496}
497
498void KListView::slotOnItem( QListViewItem *item )
499{
500 QPoint vp = viewport()->mapFromGlobal( QCursor::pos() );
501 if ( item && isExecuteArea( vp.x() ) && (d->autoSelectDelay > -1) && d->bUseSingle ) {
502 d->autoSelect.start( d->autoSelectDelay, true );
503 d->pCurrentItem = item;
504 }
505}
506
507void KListView::slotOnViewport()
508{
509 if ( d->bChangeCursorOverItem )
510 viewport()->unsetCursor();
511
512 d->autoSelect.stop();
513 d->pCurrentItem = 0L;
514}
515
516void KListView::slotSettingsChanged(int category)
517{
518qDebug("KListView::slotSettingsChanged has to be verified");
519/*US
520
521 switch (category)
522 {
523 case KApplication::SETTINGS_MOUSE:
524 d->dragDelay = KGlobalSettings::dndEventDelay();
525 d->bUseSingle = KGlobalSettings::singleClick();
526
527 disconnect(this, SIGNAL (mouseButtonClicked (int, QListViewItem*, const QPoint &, int)),
528 this, SLOT (slotMouseButtonClicked (int, QListViewItem*, const QPoint &, int)));
529
530 if( d->bUseSingle )
531 connect (this, SIGNAL (mouseButtonClicked (int, QListViewItem*, const QPoint &, int)),
532 this, SLOT (slotMouseButtonClicked( int, QListViewItem*, const QPoint &, int)));
533
534 d->bChangeCursorOverItem = KGlobalSettings::changeCursorOverIcon();
535 d->autoSelectDelay = KGlobalSettings::autoSelectDelay();
536
537 if( !d->bUseSingle || !d->bChangeCursorOverItem )
538 viewport()->unsetCursor();
539
540 break;
541
542 case KApplication::SETTINGS_POPUPMENU:
543 d->contextMenuKey = KGlobalSettings::contextMenuKey ();
544 d->showContextMenusOnPress = KGlobalSettings::showContextMenusOnPress ();
545
546 if (d->showContextMenusOnPress)
547 {
548 disconnect (0L, 0L, this, SLOT (emitContextMenu (QListViewItem*, const QPoint&, int)));
549
550 connect(this, SIGNAL (rightButtonPressed (QListViewItem*, const QPoint&, int)),
551 this, SLOT (emitContextMenu (QListViewItem*, const QPoint&, int)));
552 }
553 else
554 {
555 disconnect (0L, 0L, this, SLOT (emitContextMenu (QListViewItem*, const QPoint&, int)));
556
557 connect(this, SIGNAL (rightButtonClicked (QListViewItem*, const QPoint&, int)),
558 this, SLOT (emitContextMenu (QListViewItem*, const QPoint&, int)));
559 }
560 break;
561
562 default:
563 break;
564 }
565*/
566
567 if( d->bUseSingle )
568 connect (this, SIGNAL (mouseButtonClicked (int, QListViewItem*, const QPoint &, int)),
569 this, SLOT (slotMouseButtonClicked( int, QListViewItem*, const QPoint &, int)));
570
571}
572
573void KListView::slotAutoSelect()
574{
575 // check that the item still exists
576 if( itemIndex( d->pCurrentItem ) == -1 )
577 return;
578
579 if (!isActiveWindow())
580 {
581 d->autoSelect.stop();
582 return;
583 }
584
585 //Give this widget the keyboard focus.
586 if( !hasFocus() )
587 setFocus();
588
589 QListViewItem* previousItem = currentItem();
590 setCurrentItem( d->pCurrentItem );
591
592#if 0
593#ifndef Q_WS_QWS
594 // FIXME(E): Implement for Qt Embedded
595 if( d->pCurrentItem ) {
596 //Shift pressed?
597 if( (keybstate & ShiftMask) ) {
598 bool block = signalsBlocked();
599 blockSignals( true );
600
601 //No Ctrl? Then clear before!
602 if( !(keybstate & ControlMask) )
603 clearSelection();
604
605 bool select = !d->pCurrentItem->isSelected();
606 bool update = viewport()->isUpdatesEnabled();
607 viewport()->setUpdatesEnabled( false );
608
609 bool down = previousItem->itemPos() < d->pCurrentItem->itemPos();
610 QListViewItemIterator lit( down ? previousItem : d->pCurrentItem );
611 for ( ; lit.current(); ++lit ) {
612 if ( down && lit.current() == d->pCurrentItem ) {
613 d->pCurrentItem->setSelected( select );
614 break;
615 }
616 if ( !down && lit.current() == previousItem ) {
617 previousItem->setSelected( select );
618 break;
619 }
620 lit.current()->setSelected( select );
621 }
622
623 blockSignals( block );
624 viewport()->setUpdatesEnabled( update );
625 triggerUpdate();
626
627 emit selectionChanged();
628
629 if( selectionMode() == QListView::Single )
630 emit selectionChanged( d->pCurrentItem );
631 }
632 else if( (keybstate & ControlMask) )
633 setSelected( d->pCurrentItem, !d->pCurrentItem->isSelected() );
634 else {
635 bool block = signalsBlocked();
636 blockSignals( true );
637
638 if( !d->pCurrentItem->isSelected() )
639 clearSelection();
640
641 blockSignals( block );
642
643 setSelected( d->pCurrentItem, true );
644 }
645 }
646 else
647 kdDebug() << "KListView::slotAutoSelect: Thats not supposed to happen!!!!" << endl;
648#endif
649#endif
650}
651
652void KListView::slotHeaderChanged()
653{
654 if (d->fullWidth && columns())
655 {
656 int w = 0;
657 for (int i = 0; i < columns() - 1; ++i) w += columnWidth(i);
658 setColumnWidth( columns() - 1, viewport()->width() - w - 1 );
659 }
660}
661
662void KListView::emitExecute( QListViewItem *item, const QPoint &pos, int c )
663{
664 if( isExecuteArea( viewport()->mapFromGlobal(pos) ) ) {
665
666 // Double click mode ?
667 if ( !d->bUseSingle )
668 {
669 emit executed( item );
670 emit executed( item, pos, c );
671 }
672 else
673 {
674#if 0
675#ifndef Q_WS_QWS
676 // FIXME(E): Implement for Qt Embedded
677 Window root;
678 Window child;
679 int root_x, root_y, win_x, win_y;
680 uint keybstate;
681 XQueryPointer( qt_xdisplay(), qt_xrootwin(), &root, &child,
682 &root_x, &root_y, &win_x, &win_y, &keybstate );
683
684 d->autoSelect.stop();
685
686 //Dont emit executed if in SC mode and Shift or Ctrl are pressed
687 if( !( ((keybstate & ShiftMask) || (keybstate & ControlMask)) ) ) {
688 emit executed( item );
689 emit executed( item, pos, c );
690 }
691#endif
692#endif
693 }
694 }
695}
696
697void KListView::focusInEvent( QFocusEvent *fe )
698{
699 // kdDebug()<<"KListView::focusInEvent()"<<endl;
700 QListView::focusInEvent( fe );
701 if ((d->selectedBySimpleMove)
702 && (d->selectionMode == FileManager)
703 && (fe->reason()!=QFocusEvent::Popup)
704 && (fe->reason()!=QFocusEvent::ActiveWindow)
705 && (currentItem()!=0))
706 {
707 currentItem()->setSelected(true);
708 currentItem()->repaint();
709 emit selectionChanged();
710 };
711}
712
713void KListView::focusOutEvent( QFocusEvent *fe )
714{
715 cleanDropVisualizer();
716 cleanItemHighlighter();
717
718 d->autoSelect.stop();
719
720 if ((d->selectedBySimpleMove)
721 && (d->selectionMode == FileManager)
722 && (fe->reason()!=QFocusEvent::Popup)
723 && (fe->reason()!=QFocusEvent::ActiveWindow)
724 && (currentItem()!=0)
725/*US && (!d->editor->isVisible()) */
726 )
727 {
728 currentItem()->setSelected(false);
729 currentItem()->repaint();
730 emit selectionChanged();
731 };
732
733 QListView::focusOutEvent( fe );
734}
735
736void KListView::leaveEvent( QEvent *e )
737{
738 d->autoSelect.stop();
739
740 QListView::leaveEvent( e );
741}
742
743bool KListView::event( QEvent *e )
744{
745 if (e->type() == QEvent::ApplicationPaletteChange) {
746qDebug("KListView::event make alternate color configurable");
747//US d->alternateBackground=KGlobalSettings::alternateBackgroundColor();
748 d->alternateBackground = QColor(240, 240, 240);
749 }
750
751 return QListView::event(e);
752}
753
754void KListView::contentsMousePressEvent( QMouseEvent *e )
755{
756 if( (selectionModeExt() == Extended) && (e->state() & ShiftButton) && !(e->state() & ControlButton) )
757 {
758 bool block = signalsBlocked();
759 blockSignals( true );
760
761 clearSelection();
762
763 blockSignals( block );
764 }
765 else if ((selectionModeExt()==FileManager) && (d->selectedBySimpleMove))
766 {
767 d->selectedBySimpleMove=false;
768 d->selectedUsingMouse=true;
769 if (currentItem()!=0)
770 {
771 currentItem()->setSelected(false);
772 currentItem()->repaint();
773// emit selectionChanged();
774 };
775 };
776
777 QPoint p( contentsToViewport( e->pos() ) );
778 QListViewItem *at = itemAt (p);
779
780 // true if the root decoration of the item "at" was clicked (i.e. the +/- sign)
781 bool rootDecoClicked = at
782 && ( p.x() <= header()->cellPos( header()->mapToActual( 0 ) ) +
783 treeStepSize() * ( at->depth() + ( rootIsDecorated() ? 1 : 0) ) + itemMargin() )
784 && ( p.x() >= header()->cellPos( header()->mapToActual( 0 ) ) );
785
786 if (e->button() == LeftButton && !rootDecoClicked)
787 {
788 //Start a drag
789 d->startDragPos = e->pos();
790
791 if (at)
792 {
793 d->validDrag = true;
794 d->pressedOnSelected = at->isSelected();
795 }
796 }
797
798 QListView::contentsMousePressEvent( e );
799}
800
801void KListView::contentsMouseMoveEvent( QMouseEvent *e )
802{
803 if (!dragEnabled() || d->startDragPos.isNull() || !d->validDrag) {
804 QListView::contentsMouseMoveEvent (e);
805 return;
806 }
807
808 QPoint vp = contentsToViewport(e->pos());
809 QListViewItem *item = itemAt( vp );
810
811 //do we process cursor changes at all?
812 if ( item && d->bChangeCursorOverItem && d->bUseSingle )
813 {
814 //Cursor moved on a new item or in/out the execute area
815 if( (item != d->pCurrentItem) ||
816 (isExecuteArea(vp) != d->cursorInExecuteArea) )
817 {
818 d->cursorInExecuteArea = isExecuteArea(vp);
819qDebug("KListView::contentsMouseMoveEvent drag&drop not supported yet");
820/*US
821 if( d->cursorInExecuteArea ) //cursor moved in execute area
822 viewport()->setCursor( KCursor::handCursor() );
823 else //cursor moved out of execute area
824 viewport()->unsetCursor();
825*/
826 }
827 }
828
829 bool dragOn = dragEnabled();
830 QPoint newPos = e->pos();
831 if (dragOn && d->validDrag &&
832 (newPos.x() > d->startDragPos.x()+d->dragDelay ||
833 newPos.x() < d->startDragPos.x()-d->dragDelay ||
834 newPos.y() > d->startDragPos.y()+d->dragDelay ||
835 newPos.y() < d->startDragPos.y()-d->dragDelay))
836 //(d->startDragPos - e->pos()).manhattanLength() > QApplication::startDragDistance())
837 {
838 QListView::contentsMouseReleaseEvent( 0 );
839 startDrag();
840 d->startDragPos = QPoint();
841 d->validDrag = false;
842 }
843}
844
845void KListView::contentsMouseReleaseEvent( QMouseEvent *e )
846{
847 if (e->button() == LeftButton)
848 {
849 // If the row was already selected, maybe we want to start an in-place editing
850 if ( d->pressedOnSelected && itemsRenameable() )
851 {
852 QPoint p( contentsToViewport( e->pos() ) );
853 QListViewItem *at = itemAt (p);
854 if ( at )
855 {
856 // true if the root decoration of the item "at" was clicked (i.e. the +/- sign)
857 bool rootDecoClicked =
858 ( p.x() <= header()->cellPos( header()->mapToActual( 0 ) ) +
859 treeStepSize() * ( at->depth() + ( rootIsDecorated() ? 1 : 0) ) + itemMargin() )
860 && ( p.x() >= header()->cellPos( header()->mapToActual( 0 ) ) );
861
862 if (!rootDecoClicked)
863 {
864 int col = header()->mapToLogical( header()->cellAt( p.x() ) );
865 if ( d->renameable.contains(col) )
866 rename(at, col);
867 }
868 }
869 }
870
871 d->pressedOnSelected = false;
872 d->validDrag = false;
873 d->startDragPos = QPoint();
874 }
875 QListView::contentsMouseReleaseEvent( e );
876}
877
878void KListView::contentsMouseDoubleClickEvent ( QMouseEvent *e )
879{
880 // We don't want to call the parent method because it does setOpen,
881 // whereas we don't do it in single click mode... (David)
882 //QListView::contentsMouseDoubleClickEvent( e );
883
884 QPoint vp = contentsToViewport(e->pos());
885 QListViewItem *item = itemAt( vp );
886 emit QListView::doubleClicked( item ); // we do it now
887
888 int col = item ? header()->mapToLogical( header()->cellAt( vp.x() ) ) : -1;
889
890 if( item ) {
891 emit doubleClicked( item, e->globalPos(), col );
892
893 if( (e->button() == LeftButton) && !d->bUseSingle )
894 emitExecute( item, e->globalPos(), col );
895 }
896}
897
898void KListView::slotMouseButtonClicked( int btn, QListViewItem *item, const QPoint &pos, int c )
899{
900 if( (btn == LeftButton) && item )
901 emitExecute(item, pos, c);
902}
903
904void KListView::contentsDropEvent(QDropEvent* e)
905{
906qDebug("KListView::contentsDropEvent drag&drop not supported yet");
907/*US
908 cleanDropVisualizer();
909 cleanItemHighlighter();
910 d->dragExpand.stop();
911
912 if (acceptDrag (e))
913 {
914 e->acceptAction();
915 QListViewItem *afterme;
916 QListViewItem *parent;
917 findDrop(e->pos(), parent, afterme);
918
919 if (e->source() == viewport() && itemsMovable())
920 movableDropEvent(parent, afterme);
921 else
922 {
923
924 emit dropped(e, afterme);
925 emit dropped(this, e, afterme);
926 emit dropped(e, parent, afterme);
927 emit dropped(this, e, parent, afterme);
928
929 }
930 }
931*/
932
933}
934
935void KListView::movableDropEvent (QListViewItem* parent, QListViewItem* afterme)
936{
937 QPtrList<QListViewItem> items, afterFirsts, afterNows;
938 QListViewItem *current=currentItem();
939 bool hasMoved=false;
940 for (QListViewItem *i = firstChild(), *iNext=0; i != 0; i = iNext)
941 {
942 iNext=i->itemBelow();
943 if (!i->isSelected())
944 continue;
945
946 // don't drop an item after itself, or else
947 // it moves to the top of the list
948 if (i==afterme)
949 continue;
950
951 i->setSelected(false);
952
953 QListViewItem *afterFirst = i->itemAbove();
954
955 if (!hasMoved)
956 {
957 emit aboutToMove();
958 hasMoved=true;
959 }
960
961 moveItem(i, parent, afterme);
962
963 // ###### This should include the new parent !!! -> KDE 3.0
964 // If you need this right now, have a look at keditbookmarks.
965 emit moved(i, afterFirst, afterme);
966
967 items.append (i);
968 afterFirsts.append (afterFirst);
969 afterNows.append (afterme);
970
971 afterme = i;
972 }
973 clearSelection();
974 for (QListViewItem *i=items.first(); i != 0; i=items.next() )
975 i->setSelected(true);
976 if (current)
977 setCurrentItem(current);
978
979 emit moved(items,afterFirsts,afterNows);
980
981 if (firstChild())
982 emit moved();
983}
984
985void KListView::contentsDragMoveEvent(QDragMoveEvent *event)
986{
987qDebug("KListView::contentsDropEvent drag&drop not supported yet");
988/*US
989 if (acceptDrag(event))
990 {
991 event->acceptAction();
992 //Clean up the view
993
994 findDrop(event->pos(), d->parentItemDrop, d->afterItemDrop);
995 QPoint vp = contentsToViewport( event->pos() );
996 QListViewItem *item = isExecuteArea( vp ) ? itemAt( vp ) : 0L;
997
998 if ( item != d->dragOverItem )
999 {
1000 d->dragExpand.stop();
1001 d->dragOverItem = item;
1002 d->dragOverPoint = vp;
1003 if ( d->dragOverItem && d->dragOverItem->isExpandable() && !d->dragOverItem->isOpen() )
1004 d->dragExpand.start( QApplication::startDragTime(), true );
1005 }
1006 if (dropVisualizer())
1007 {
1008 QRect tmpRect = drawDropVisualizer(0, d->parentItemDrop, d->afterItemDrop);
1009 if (tmpRect != d->mOldDropVisualizer)
1010 {
1011 cleanDropVisualizer();
1012 d->mOldDropVisualizer=tmpRect;
1013 viewport()->repaint(tmpRect);
1014 }
1015 }
1016 if (dropHighlighter())
1017 {
1018 QRect tmpRect = drawItemHighlighter(0, d->afterItemDrop);
1019 if (tmpRect != d->mOldDropHighlighter)
1020 {
1021 cleanItemHighlighter();
1022 d->mOldDropHighlighter=tmpRect;
1023 viewport()->repaint(tmpRect);
1024 }
1025 }
1026 }
1027 else
1028 event->ignore();
1029*/
1030}
1031
1032void KListView::slotDragExpand()
1033{
1034 if ( itemAt( d->dragOverPoint ) == d->dragOverItem )
1035 d->dragOverItem->setOpen( true );
1036}
1037
1038void KListView::contentsDragLeaveEvent (QDragLeaveEvent*)
1039{
1040 d->dragExpand.stop();
1041 cleanDropVisualizer();
1042 cleanItemHighlighter();
1043}
1044
1045void KListView::cleanDropVisualizer()
1046{
1047 if (d->mOldDropVisualizer.isValid())
1048 {
1049 QRect rect=d->mOldDropVisualizer;
1050 d->mOldDropVisualizer = QRect();
1051 viewport()->repaint(rect, true);
1052 }
1053}
1054
1055int KListView::depthToPixels( int depth )
1056{
1057 return treeStepSize() * ( depth + (rootIsDecorated() ? 1 : 0) ) + itemMargin();
1058}
1059
1060void KListView::findDrop(const QPoint &pos, QListViewItem *&parent, QListViewItem *&after)
1061{
1062 QPoint p (contentsToViewport(pos));
1063
1064 // Get the position to put it in
1065 QListViewItem *atpos = itemAt(p);
1066
1067 QListViewItem *above;
1068 if (!atpos) // put it at the end
1069 above = lastItem();
1070 else
1071 {
1072 // Get the closest item before us ('atpos' or the one above, if any)
1073 if (p.y() - itemRect(atpos).topLeft().y() < (atpos->height()/2))
1074 above = atpos->itemAbove();
1075 else
1076 above = atpos;
1077 }
1078
1079 if (above)
1080 {
1081 // Now, we know we want to go after "above". But as a child or as a sibling ?
1082 // We have to ask the "above" item if it accepts children.
1083 if (above->isExpandable())
1084 {
1085 // The mouse is sufficiently on the right ? - doesn't matter if 'above' has visible children
1086 if (p.x() >= depthToPixels( above->depth() + 1 ) ||
1087 (above->isOpen() && above->childCount() > 0) )
1088 {
1089 parent = above;
1090 after = 0L;
1091 return;
1092 }
1093 }
1094
1095 // Ok, there's one more level of complexity. We may want to become a new
1096 // sibling, but of an upper-level group, rather than the "above" item
1097 QListViewItem * betterAbove = above->parent();
1098 QListViewItem * last = above;
1099 while ( betterAbove )
1100 {
1101 // We are allowed to become a sibling of "betterAbove" only if we are
1102 // after its last child
1103 if ( last->nextSibling() == 0 )
1104 {
1105 if (p.x() < depthToPixels ( betterAbove->depth() + 1 ))
1106 above = betterAbove; // store this one, but don't stop yet, there may be a better one
1107 else
1108 break; // not enough on the left, so stop
1109 last = betterAbove;
1110 betterAbove = betterAbove->parent(); // up one level
1111 } else
1112 break; // we're among the child of betterAbove, not after the last one
1113 }
1114 }
1115 // set as sibling
1116 after = above;
1117 parent = after ? after->parent() : 0L ;
1118}
1119
1120QListViewItem* KListView::lastChild () const
1121{
1122 QListViewItem* lastchild = firstChild();
1123
1124 if (lastchild)
1125 for (; lastchild->nextSibling(); lastchild = lastchild->nextSibling());
1126
1127 return lastchild;
1128}
1129
1130QListViewItem *KListView::lastItem() const
1131{
1132 QListViewItem* last = lastChild();
1133
1134 for (QListViewItemIterator it (last); it.current(); ++it)
1135 last = it.current();
1136
1137 return last;
1138}
1139
1140KLineEdit *KListView::renameLineEdit() const
1141{
1142//US return d->editor;
1143qDebug("KListView::renameLineEdit returns 0. Might crash");
1144return 0;
1145}
1146
1147void KListView::startDrag()
1148{
1149qDebug("KListView::startDrag drag&drop not supported yet.");
1150/*US
1151 QDragObject *drag = dragObject();
1152
1153 if (!drag)
1154 return;
1155
1156 if (drag->drag() && drag->target() != viewport())
1157 emit moved();
1158*/
1159}
1160
1161QDragObject *KListView::dragObject()
1162{
1163 if (!currentItem())
1164 return 0;
1165
1166 return new QStoredDrag("application/x-qlistviewitem", viewport());
1167}
1168
1169void KListView::setItemsMovable(bool b)
1170{
1171 d->itemsMovable=b;
1172}
1173
1174bool KListView::itemsMovable() const
1175{
1176 return d->itemsMovable;
1177}
1178
1179void KListView::setItemsRenameable(bool b)
1180{
1181 d->itemsRenameable=b;
1182}
1183
1184bool KListView::itemsRenameable() const
1185{
1186 return d->itemsRenameable;
1187}
1188
1189
1190void KListView::setDragEnabled(bool b)
1191{
1192 d->dragEnabled=b;
1193}
1194
1195bool KListView::dragEnabled() const
1196{
1197 return d->dragEnabled;
1198}
1199
1200void KListView::setAutoOpen(bool b)
1201{
1202 d->autoOpen=b;
1203}
1204
1205bool KListView::autoOpen() const
1206{
1207 return d->autoOpen;
1208}
1209
1210bool KListView::dropVisualizer() const
1211{
1212 return d->dropVisualizer;
1213}
1214
1215void KListView::setDropVisualizer(bool b)
1216{
1217 d->dropVisualizer=b;
1218}
1219
1220QPtrList<QListViewItem> KListView::selectedItems() const
1221{
1222 QPtrList<QListViewItem> list;
1223 for (QListViewItem *i=firstChild(); i!=0; i=i->itemBelow())
1224 if (i->isSelected()) list.append(i);
1225 return list;
1226}
1227
1228
1229void KListView::moveItem(QListViewItem *item, QListViewItem *parent, QListViewItem *after)
1230{
1231 // sanity check - don't move a item into it's own child structure
1232 QListViewItem *i = parent;
1233 while(i)
1234 {
1235 if(i == item)
1236 return;
1237 i = i->parent();
1238 }
1239
1240 // Basically reimplementing the QListViewItem(QListViewItem*, QListViewItem*) constructor
1241 // in here, without ever deleting the item.
1242 if (item->parent())
1243 item->parent()->takeItem(item);
1244 else
1245 takeItem(item);
1246
1247 if (parent)
1248 parent->insertItem(item);
1249 else
1250 insertItem(item);
1251
1252 if (after)
1253 ;//item->moveToJustAfter(after);
1254}
1255
1256void KListView::contentsDragEnterEvent(QDragEnterEvent *event)
1257{
1258qDebug("KListView::contentsDragEnterEvent drag&drop not supported yet.");
1259/*US
1260 if (acceptDrag (event))
1261 event->accept();
1262*/
1263}
1264
1265void KListView::setDropVisualizerWidth (int w)
1266{
1267 d->mDropVisualizerWidth = w > 0 ? w : 1;
1268}
1269
1270QRect KListView::drawDropVisualizer(QPainter *p, QListViewItem *parent,
1271 QListViewItem *after)
1272{
1273 QRect insertmarker;
1274
1275 if (!after && !parent)
1276 insertmarker = QRect (0, 0, viewport()->width(), d->mDropVisualizerWidth/2);
1277 else
1278 {
1279 int level = 0;
1280 if (after)
1281 {
1282 QListViewItem* it = 0L;
1283 if (after->isOpen())
1284 {
1285 // Look for the last child (recursively)
1286 it = after->firstChild();
1287 if (it)
1288 while (it->nextSibling() || it->firstChild())
1289 if ( it->nextSibling() )
1290 it = it->nextSibling();
1291 else
1292 it = it->firstChild();
1293 }
1294
1295 insertmarker = itemRect (it ? it : after);
1296 level = after->depth();
1297 }
1298 else if (parent)
1299 {
1300 insertmarker = itemRect (parent);
1301 level = parent->depth() + 1;
1302 }
1303 insertmarker.setLeft( treeStepSize() * ( level + (rootIsDecorated() ? 1 : 0) ) + itemMargin() );
1304 insertmarker.setRight (viewport()->width());
1305 insertmarker.setTop (insertmarker.bottom() - d->mDropVisualizerWidth/2 + 1);
1306 insertmarker.setBottom (insertmarker.bottom() + d->mDropVisualizerWidth/2);
1307 }
1308
1309 // This is not used anymore, at least by KListView itself (see viewportPaintEvent)
1310 // Remove for KDE 3.0.
1311 if (p)
1312 p->fillRect(insertmarker, Dense4Pattern);
1313
1314 return insertmarker;
1315}
1316
1317QRect KListView::drawItemHighlighter(QPainter *painter, QListViewItem *item)
1318{
1319 QRect r;
1320
1321 if (item)
1322 {
1323 r = itemRect(item);
1324 r.setLeft(r.left()+(item->depth()+1)*treeStepSize());
1325 if (painter) {
1326//US style().drawPrimitive(QStyle::PE_FocusRect, painter, r, colorGroup(),
1327//US QStyle::Style_FocusAtBorder, colorGroup().highlight());
1328 const QColor* pHighl = &(colorGroup().highlight());
1329 //LR style().drawFocusRect(painter, r, colorGroup(), pHighl, true);
1330
1331qDebug("KListView::drawItemHighlighter has to be verified");
1332
1333 }
1334
1335 }
1336
1337 return r;
1338}
1339
1340void KListView::cleanItemHighlighter ()
1341{
1342 if (d->mOldDropHighlighter.isValid())
1343 {
1344 QRect rect=d->mOldDropHighlighter;
1345 d->mOldDropHighlighter = QRect();
1346 viewport()->repaint(rect, true);
1347 }
1348}
1349
1350void KListView::rename(QListViewItem *item, int c)
1351{
1352 if (d->renameable.contains(c))
1353 {
1354 ensureItemVisible(item);
1355//US d->editor->load(item,c);
1356qDebug("KListView::rename has to be verified");
1357
1358 }
1359}
1360
1361bool KListView::isRenameable (int col) const
1362{
1363 return d->renameable.contains(col);
1364}
1365
1366void KListView::setRenameable (int col, bool yesno)
1367{
1368 if (col>=header()->count()) return;
1369
1370 d->renameable.remove(col);
1371 if (yesno && d->renameable.find(col)==d->renameable.end())
1372 d->renameable+=col;
1373 else if (!yesno && d->renameable.find(col)!=d->renameable.end())
1374 d->renameable.remove(col);
1375}
1376
1377void KListView::doneEditing(QListViewItem *item, int row)
1378{
1379 emit itemRenamed(item, item->text(row), row);
1380 emit itemRenamed(item);
1381}
1382
1383bool KListView::acceptDrag(QDropEvent* e) const
1384{
1385qDebug("KListView::acceptDrag drag&drop not supported yet");
1386//US return acceptDrops() && itemsMovable() && (e->source()==viewport());
1387return false;
1388}
1389
1390void KListView::setCreateChildren(bool b)
1391{
1392 d->createChildren=b;
1393}
1394
1395bool KListView::createChildren() const
1396{
1397 return d->createChildren;
1398}
1399
1400
1401int KListView::tooltipColumn() const
1402{
1403 return d->tooltipColumn;
1404}
1405
1406void KListView::setTooltipColumn(int column)
1407{
1408 d->tooltipColumn=column;
1409}
1410
1411void KListView::setDropHighlighter(bool b)
1412{
1413 d->dropHighlighter=b;
1414}
1415
1416bool KListView::dropHighlighter() const
1417{
1418 return d->dropHighlighter;
1419}
1420
1421bool KListView::showTooltip(QListViewItem *item, const QPoint &, int column) const
1422{
1423 return ((tooltip(item, column).length()>0) && (column==tooltipColumn()));
1424}
1425
1426QString KListView::tooltip(QListViewItem *item, int column) const
1427{
1428 return item->text(column);
1429}
1430
1431void KListView::setTabOrderedRenaming(bool b)
1432{
1433 d->tabRename = b;
1434}
1435
1436bool KListView::tabOrderedRenaming() const
1437{
1438 return d->tabRename;
1439}
1440
1441void KListView::keyPressEvent (QKeyEvent* e)
1442{
1443 //don't we need a contextMenuModifier too ? (aleXXX)
1444 if (e->key() == d->contextMenuKey)
1445 {
1446 emit menuShortCutPressed (this, currentItem());
1447 return;
1448 }
1449 if (e->key() == Qt::Key_Delete || e->key() == Qt::Key_Backspace)
1450 {
1451 emit signalDelete ( );
1452 return;
1453 }
1454
1455 if (d->selectionMode != FileManager)
1456 QListView::keyPressEvent (e);
1457 else
1458 fileManagerKeyPressEvent (e);
1459}
1460
1461void KListView::activateAutomaticSelection()
1462{
1463 d->selectedBySimpleMove=true;
1464 d->selectedUsingMouse=false;
1465 if (currentItem()!=0)
1466 {
1467 selectAll(false);
1468 currentItem()->setSelected(true);
1469 currentItem()->repaint();
1470 emit selectionChanged();
1471 };
1472}
1473
1474void KListView::deactivateAutomaticSelection()
1475{
1476 d->selectedBySimpleMove=false;
1477}
1478
1479bool KListView::automaticSelection() const
1480{
1481 return d->selectedBySimpleMove;
1482}
1483
1484void KListView::fileManagerKeyPressEvent (QKeyEvent* e)
1485{
1486 //don't care whether it's on the keypad or not
1487 int e_state=(e->state() & ~Keypad);
1488
1489 int oldSelectionDirection(d->selectionDirection);
1490
1491 if ((e->key()!=Key_Shift) && (e->key()!=Key_Control)
1492 && (e->key()!=Key_Meta) && (e->key()!=Key_Alt))
1493 {
1494 if ((e_state==ShiftButton) && (!d->wasShiftEvent) && (!d->selectedBySimpleMove))
1495 selectAll(FALSE);
1496 d->selectionDirection=0;
1497 d->wasShiftEvent = (e_state == ShiftButton);
1498 };
1499
1500 //d->wasShiftEvent = (e_state == ShiftButton);
1501
1502
1503 QListViewItem* item = currentItem();
1504 if (item==0) return;
1505
1506 QListViewItem* repaintItem1 = item;
1507 QListViewItem* repaintItem2 = 0L;
1508 QListViewItem* visItem = 0L;
1509
1510 QListViewItem* nextItem = 0L;
1511 int items = 0;
1512
1513 bool shiftOrCtrl((e_state==ControlButton) || (e_state==ShiftButton));
1514 int selectedItems(0);
1515 for (QListViewItem *tmpItem=firstChild(); tmpItem!=0; tmpItem=tmpItem->nextSibling())
1516 if (tmpItem->isSelected()) selectedItems++;
1517
1518 if (((selectedItems==0) || ((selectedItems==1) && (d->selectedUsingMouse)))
1519 && (e_state==NoButton)
1520 && ((e->key()==Key_Down)
1521 || (e->key()==Key_Up)
1522 || (e->key()==Key_Next)
1523 || (e->key()==Key_Prior)
1524 || (e->key()==Key_Home)
1525 || (e->key()==Key_End)))
1526 {
1527 d->selectedBySimpleMove=true;
1528 d->selectedUsingMouse=false;
1529 }
1530 else if (selectedItems>1)
1531 d->selectedBySimpleMove=false;
1532
1533 bool emitSelectionChanged(false);
1534
1535 switch (e->key())
1536 {
1537 case Key_Escape:
1538 selectAll(FALSE);
1539 emitSelectionChanged=TRUE;
1540 break;
1541
1542 case Key_Space:
1543 //toggle selection of current item
1544 if (d->selectedBySimpleMove)
1545 d->selectedBySimpleMove=false;
1546 item->setSelected(!item->isSelected());
1547 emitSelectionChanged=TRUE;
1548 break;
1549
1550 case Key_Insert:
1551 //toggle selection of current item and move to the next item
1552 if (d->selectedBySimpleMove)
1553 {
1554 d->selectedBySimpleMove=false;
1555 if (!item->isSelected()) item->setSelected(TRUE);
1556 }
1557 else
1558 {
1559 item->setSelected(!item->isSelected());
1560 };
1561
1562 nextItem=item->itemBelow();
1563
1564 if (nextItem!=0)
1565 {
1566 repaintItem2=nextItem;
1567 visItem=nextItem;
1568 setCurrentItem(nextItem);
1569 };
1570 d->selectionDirection=1;
1571 emitSelectionChanged=TRUE;
1572 break;
1573
1574 case Key_Down:
1575 nextItem=item->itemBelow();
1576 //toggle selection of current item and move to the next item
1577 if (shiftOrCtrl)
1578 {
1579 d->selectionDirection=1;
1580 if (d->selectedBySimpleMove)
1581 d->selectedBySimpleMove=false;
1582 else
1583 {
1584 if (oldSelectionDirection!=-1)
1585 {
1586 item->setSelected(!item->isSelected());
1587 emitSelectionChanged=TRUE;
1588 };
1589 };
1590 }
1591 else if ((d->selectedBySimpleMove) && (nextItem!=0))
1592 {
1593 item->setSelected(false);
1594 emitSelectionChanged=TRUE;
1595 };
1596
1597 if (nextItem!=0)
1598 {
1599 if (d->selectedBySimpleMove)
1600 nextItem->setSelected(true);
1601 repaintItem2=nextItem;
1602 visItem=nextItem;
1603 setCurrentItem(nextItem);
1604 };
1605 break;
1606
1607 case Key_Up:
1608 nextItem=item->itemAbove();
1609 d->selectionDirection=-1;
1610 //move to the prev. item and toggle selection of this one
1611 // => No, can't select the last item, with this. For symmetry, let's
1612 // toggle selection and THEN move up, just like we do in down (David)
1613 if (shiftOrCtrl)
1614 {
1615 if (d->selectedBySimpleMove)
1616 d->selectedBySimpleMove=false;
1617 else
1618 {
1619 if (oldSelectionDirection!=1)
1620 {
1621 item->setSelected(!item->isSelected());
1622 emitSelectionChanged=TRUE;
1623 };
1624 }
1625 }
1626 else if ((d->selectedBySimpleMove) && (nextItem!=0))
1627 {
1628 item->setSelected(false);
1629 emitSelectionChanged=TRUE;
1630 };
1631
1632 if (nextItem!=0)
1633 {
1634 if (d->selectedBySimpleMove)
1635 nextItem->setSelected(true);
1636 repaintItem2=nextItem;
1637 visItem=nextItem;
1638 setCurrentItem(nextItem);
1639 };
1640 break;
1641
1642 case Key_End:
1643 //move to the last item and toggle selection of all items inbetween
1644 nextItem=item;
1645 if (d->selectedBySimpleMove)
1646 item->setSelected(false);
1647 if (shiftOrCtrl)
1648 d->selectedBySimpleMove=false;
1649
1650 while(nextItem!=0)
1651 {
1652 if (shiftOrCtrl)
1653 nextItem->setSelected(!nextItem->isSelected());
1654 if (nextItem->itemBelow()==0)
1655 {
1656 if (d->selectedBySimpleMove)
1657 nextItem->setSelected(true);
1658 repaintItem2=nextItem;
1659 visItem=nextItem;
1660 setCurrentItem(nextItem);
1661 }
1662 nextItem=nextItem->itemBelow();
1663 }
1664 emitSelectionChanged=TRUE;
1665 break;
1666
1667 case Key_Home:
1668 // move to the first item and toggle selection of all items inbetween
1669 nextItem = firstChild();
1670 visItem = nextItem;
1671 repaintItem2 = visItem;
1672 if (d->selectedBySimpleMove)
1673 item->setSelected(false);
1674 if (shiftOrCtrl)
1675 {
1676 d->selectedBySimpleMove=false;
1677
1678 while ( nextItem != item )
1679 {
1680 nextItem->setSelected( !nextItem->isSelected() );
1681 nextItem = nextItem->itemBelow();
1682 }
1683 item->setSelected( !item->isSelected() );
1684 }
1685 setCurrentItem( firstChild() );
1686 emitSelectionChanged=TRUE;
1687 break;
1688
1689 case Key_Next:
1690 items=visibleHeight()/item->height();
1691 nextItem=item;
1692 if (d->selectedBySimpleMove)
1693 item->setSelected(false);
1694 if (shiftOrCtrl)
1695 {
1696 d->selectedBySimpleMove=false;
1697 d->selectionDirection=1;
1698 };
1699
1700 for (int i=0; i<items; i++)
1701 {
1702 if (shiftOrCtrl)
1703 nextItem->setSelected(!nextItem->isSelected());
1704 //the end
1705 if ((i==items-1) || (nextItem->itemBelow()==0))
1706
1707 {
1708 if (shiftOrCtrl)
1709 nextItem->setSelected(!nextItem->isSelected());
1710 if (d->selectedBySimpleMove)
1711 nextItem->setSelected(true);
1712 ensureItemVisible(nextItem);
1713 setCurrentItem(nextItem);
1714 update();
1715 if ((shiftOrCtrl) || (d->selectedBySimpleMove))
1716 {
1717 emit selectionChanged();
1718 }
1719 return;
1720 }
1721 nextItem=nextItem->itemBelow();
1722 }
1723 break;
1724
1725 case Key_Prior:
1726 items=visibleHeight()/item->height();
1727 nextItem=item;
1728 if (d->selectedBySimpleMove)
1729 item->setSelected(false);
1730 if (shiftOrCtrl)
1731 {
1732 d->selectionDirection=-1;
1733 d->selectedBySimpleMove=false;
1734 };
1735
1736 for (int i=0; i<items; i++)
1737 {
1738 if ((nextItem!=item) &&(shiftOrCtrl))
1739 nextItem->setSelected(!nextItem->isSelected());
1740 //the end
1741 if ((i==items-1) || (nextItem->itemAbove()==0))
1742
1743 {
1744 if (d->selectedBySimpleMove)
1745 nextItem->setSelected(true);
1746 ensureItemVisible(nextItem);
1747 setCurrentItem(nextItem);
1748 update();
1749 if ((shiftOrCtrl) || (d->selectedBySimpleMove))
1750 {
1751 emit selectionChanged();
1752 }
1753 return;
1754 }
1755 nextItem=nextItem->itemAbove();
1756 }
1757 break;
1758
1759 case Key_Minus:
1760 if ( item->isOpen() )
1761 setOpen( item, FALSE );
1762 break;
1763 case Key_Plus:
1764 if ( !item->isOpen() && (item->isExpandable() || item->childCount()) )
1765 setOpen( item, TRUE );
1766 break;
1767 default:
1768 bool realKey = ((e->key()!=Key_Shift) && (e->key()!=Key_Control)
1769 && (e->key()!=Key_Meta) && (e->key()!=Key_Alt));
1770
1771 bool selectCurrentItem = (d->selectedBySimpleMove) && (item->isSelected());
1772 if (realKey && selectCurrentItem)
1773 item->setSelected(false);
1774 //this is mainly for the "goto filename beginning with pressed char" feature (aleXXX)
1775 QListView::SelectionMode oldSelectionMode = selectionMode();
1776 setSelectionMode (QListView::Multi);
1777 QListView::keyPressEvent (e);
1778 setSelectionMode (oldSelectionMode);
1779 if (realKey && selectCurrentItem)
1780 {
1781 currentItem()->setSelected(true);
1782 emitSelectionChanged=TRUE;
1783 }
1784 repaintItem2=currentItem();
1785 if (realKey)
1786 visItem=currentItem();
1787 break;
1788 }
1789
1790 if (visItem)
1791 ensureItemVisible(visItem);
1792
1793 QRect ir;
1794 if (repaintItem1)
1795 ir = ir.unite( itemRect(repaintItem1) );
1796 if (repaintItem2)
1797 ir = ir.unite( itemRect(repaintItem2) );
1798
1799 if ( !ir.isEmpty() )
1800 { // rectangle to be repainted
1801 if ( ir.x() < 0 )
1802 ir.moveBy( -ir.x(), 0 );
1803 viewport()->repaint( ir, FALSE );
1804 }
1805 /*if (repaintItem1)
1806 repaintItem1->repaint();
1807 if (repaintItem2)
1808 repaintItem2->repaint();*/
1809 update();
1810 if (emitSelectionChanged)
1811 emit selectionChanged();
1812}
1813
1814void KListView::setSelectionModeExt (SelectionModeExt mode)
1815{
1816 d->selectionMode = mode;
1817
1818 switch (mode)
1819 {
1820 case Single:
1821 case Multi:
1822 case Extended:
1823 case NoSelection:
1824 setSelectionMode (static_cast<QListView::SelectionMode>(static_cast<int>(mode)));
1825 break;
1826
1827 case FileManager:
1828 setSelectionMode (QListView::Extended);
1829 break;
1830
1831 default:
1832 kdWarning () << "Warning: illegal selection mode " << int(mode) << " set!" << endl;
1833 break;
1834 }
1835}
1836
1837KListView::SelectionModeExt KListView::selectionModeExt () const
1838{
1839 return d->selectionMode;
1840}
1841
1842int KListView::itemIndex( const QListViewItem *item ) const
1843{
1844 if ( !item )
1845 return -1;
1846
1847 if ( item == firstChild() )
1848 return 0;
1849 else {
1850 QListViewItemIterator it(firstChild());
1851 uint j = 0;
1852 for (; it.current() && it.current() != item; ++it, ++j );
1853
1854 if( !it.current() )
1855 return -1;
1856
1857 return j;
1858 }
1859}
1860
1861QListViewItem* KListView::itemAtIndex(int index)
1862{
1863 if (index<0)
1864 return 0;
1865
1866 int j(0);
1867 for (QListViewItemIterator it=firstChild(); it.current(); it++)
1868 {
1869 if (j==index)
1870 return it.current();
1871 j++;
1872 };
1873 return 0;
1874}
1875
1876
1877void KListView::emitContextMenu (KListView*, QListViewItem* i)
1878{
1879 QPoint p;
1880 qDebug("KListView::emitContextMenu ");
1881
1882 if (i)
1883 p = viewport()->mapToGlobal(itemRect(i).center());
1884 else
1885 p = mapToGlobal(rect().center());
1886
1887 emit contextMenu (this, i, p);
1888}
1889
1890void KListView::emitContextMenu (QListViewItem* i, const QPoint& p, int)
1891{
1892 qDebug("KListView::emitContextMenu ");
1893 emit contextMenu (this, i, p);
1894}
1895
1896void KListView::setAcceptDrops (bool val)
1897{
1898 QListView::setAcceptDrops (val);
1899 viewport()->setAcceptDrops (val);
1900}
1901
1902int KListView::dropVisualizerWidth () const
1903{
1904 return d->mDropVisualizerWidth;
1905}
1906
1907
1908void KListView::viewportPaintEvent(QPaintEvent *e)
1909{
1910 QListView::viewportPaintEvent(e);
1911
1912 if (d->mOldDropVisualizer.isValid() && e->rect().intersects(d->mOldDropVisualizer))
1913 {
1914 QPainter painter(viewport());
1915
1916 // This is where we actually draw the drop-visualizer
1917 painter.fillRect(d->mOldDropVisualizer, Dense4Pattern);
1918 }
1919 if (d->mOldDropHighlighter.isValid() && e->rect().intersects(d->mOldDropHighlighter))
1920 {
1921 QPainter painter(viewport());
1922
1923qDebug("KListView::viewportPaintEvent has to be verified");
1924
1925 // This is where we actually draw the drop-highlighter
1926//US style().drawPrimitive(QStyle::PE_FocusRect, &painter, d->mOldDropHighlighter, colorGroup(),
1927//US QStyle::Style_FocusAtBorder);
1928
1929//LR style().drawFocusRect(&painter, d->mOldDropHighlighter, colorGroup(), (const QColor*)0, true);
1930
1931
1932 }
1933}
1934
1935void KListView::setFullWidth()
1936{
1937 setFullWidth(true);
1938}
1939
1940void KListView::setFullWidth(bool fullWidth)
1941{
1942 d->fullWidth = fullWidth;
1943//US header()->setStretchEnabled(fullWidth, columns()-1);
1944}
1945
1946bool KListView::fullWidth() const
1947{
1948 return d->fullWidth;
1949}
1950
1951int KListView::addColumn(const QString& label, int width)
1952{
1953 int result = QListView::addColumn(label, width);
1954 if (d->fullWidth) {
1955//US header()->setStretchEnabled(false, columns()-2);
1956//US header()->setStretchEnabled(true, columns()-1);
1957 }
1958 return result;
1959}
1960
1961int KListView::addColumn(const QIconSet& iconset, const QString& label, int width)
1962{
1963 int result = QListView::addColumn(iconset, label, width);
1964 if (d->fullWidth) {
1965//US header()->setStretchEnabled(false, columns()-2);
1966//US header()->setStretchEnabled(true, columns()-1);
1967 }
1968 return result;
1969}
1970
1971void KListView::removeColumn(int index)
1972{
1973 QListView::removeColumn(index);
1974//US if (d->fullWidth && index == columns()) header()->setStretchEnabled(true, columns()-1);
1975}
1976
1977void KListView::viewportResizeEvent(QResizeEvent* e)
1978{
1979 QListView::viewportResizeEvent(e);
1980}
1981
1982const QColor &KListView::alternateBackground() const
1983{
1984 return d->alternateBackground;
1985}
1986
1987void KListView::setAlternateBackground(const QColor &c)
1988{
1989 d->alternateBackground = c;
1990 repaint();
1991}
1992
1993void KListView::saveLayout(KConfig *config, const QString &group) const
1994{
1995 KConfigGroupSaver saver(config, group);
1996 QStringList widths, order;
1997 for (int i = 0; i < columns(); ++i)
1998 {
1999 widths << QString::number(columnWidth(i));
2000 order << QString::number(header()->mapToIndex(i));
2001 }
2002 config->writeEntry("ColumnWidths", widths);
2003 config->writeEntry("ColumnOrder", order);
2004 config->writeEntry("SortColumn", d->sortColumn);
2005 config->writeEntry("SortAscending", d->sortAscending);
2006}
2007
2008void KListView::restoreLayout(KConfig *config, const QString &group)
2009{
2010 KConfigGroupSaver saver(config, group);
2011 QStringList cols = config->readListEntry("ColumnWidths");
2012 int i = 0;
2013 for (QStringList::ConstIterator it = cols.begin(); it != cols.end(); ++it)
2014 setColumnWidth(i++, (*it).toInt());
2015
2016 cols = config->readListEntry("ColumnOrder");
2017 i = 0;
2018 for (QStringList::ConstIterator it = cols.begin(); it != cols.end(); ++it)
2019 header()->moveSection(i++, (*it).toInt());
2020
2021/*US I changed the following code, because hasKey is not available.
2022!!! check if my version is correct
2023 if (config->hasKey("SortColumn"))
2024 setSorting(config->readNumEntry("SortColumn"), config->readBoolEntry("SortAscending", true));
2025*/
2026 QStringList langLst = config->readListEntry( "SortColumn" );
2027 if (!langLst.isEmpty())
2028 setSorting(config->readNumEntry("SortColumn"), config->readBoolEntry("SortAscending", true));
2029}
2030
2031void KListView::setSorting(int column, bool ascending)
2032{
2033 d->sortColumn = column;
2034 d->sortAscending = ascending;
2035 QListView::setSorting(column, ascending);
2036}
2037
2038int KListView::columnSorted(void) const
2039{
2040 return d->sortColumn;
2041}
2042
2043bool KListView::ascendingSort(void) const
2044{
2045 return d->sortAscending;
2046}
2047
2048KListViewItem::KListViewItem(QListView *parent)
2049 : QListViewItem(parent)
2050{
2051 init();
2052}
2053
2054KListViewItem::KListViewItem(QListViewItem *parent)
2055 : QListViewItem(parent)
2056{
2057 init();
2058}
2059
2060KListViewItem::KListViewItem(QListView *parent, QListViewItem *after)
2061 : QListViewItem(parent, after)
2062{
2063 init();
2064}
2065
2066KListViewItem::KListViewItem(QListViewItem *parent, QListViewItem *after)
2067 : QListViewItem(parent, after)
2068{
2069 init();
2070}
2071
2072KListViewItem::KListViewItem(QListView *parent,
2073 QString label1, QString label2, QString label3, QString label4,
2074 QString label5, QString label6, QString label7, QString label8)
2075 : QListViewItem(parent, label1, label2, label3, label4, label5, label6, label7, label8)
2076{
2077 init();
2078}
2079
2080KListViewItem::KListViewItem(QListViewItem *parent,
2081 QString label1, QString label2, QString label3, QString label4,
2082 QString label5, QString label6, QString label7, QString label8)
2083 : QListViewItem(parent, label1, label2, label3, label4, label5, label6, label7, label8)
2084{
2085 init();
2086}
2087
2088KListViewItem::KListViewItem(QListView *parent, QListViewItem *after,
2089 QString label1, QString label2, QString label3, QString label4,
2090 QString label5, QString label6, QString label7, QString label8)
2091 : QListViewItem(parent, after, label1, label2, label3, label4, label5, label6, label7, label8)
2092{
2093 init();
2094}
2095
2096KListViewItem::KListViewItem(QListViewItem *parent, QListViewItem *after,
2097 QString label1, QString label2, QString label3, QString label4,
2098 QString label5, QString label6, QString label7, QString label8)
2099 : QListViewItem(parent, after, label1, label2, label3, label4, label5, label6, label7, label8)
2100{
2101 init();
2102}
2103
2104KListViewItem::~KListViewItem()
2105{
2106}
2107
2108void KListViewItem::init()
2109{
2110 m_known = false;
2111}
2112
2113const QColor &KListViewItem::backgroundColor()
2114{
2115 if (isAlternate())
2116 return static_cast< KListView* >(listView())->alternateBackground();
2117 return listView()->viewport()->colorGroup().base();
2118}
2119
2120bool KListViewItem::isAlternate()
2121{
2122 KListView *lv = static_cast<KListView *>(listView());
2123 if (lv && lv->alternateBackground().isValid())
2124 {
2125 KListViewItem *above = 0;
2126//US above = dynamic_cast<KListViewItem *>(itemAbove());
2127 above = (KListViewItem *)(itemAbove());
2128 m_known = above ? above->m_known : true;
2129 if (m_known)
2130 {
2131 m_odd = above ? !above->m_odd : false;
2132 }
2133 else
2134 {
2135 KListViewItem *item;
2136 bool previous = true;
2137 if (parent())
2138 {
2139//US item = dynamic_cast<KListViewItem *>(parent());
2140 item = (KListViewItem *)(parent());
2141 if (item)
2142 previous = item->m_odd;
2143//US item = dynamic_cast<KListViewItem *>(parent()->firstChild());
2144 item = (KListViewItem *)(parent()->firstChild());
2145 }
2146 else
2147 {
2148//US item = dynamic_cast<KListViewItem *>(lv->firstChild());
2149 item = (KListViewItem *)(lv->firstChild());
2150 }
2151
2152 while(item)
2153 {
2154 item->m_odd = previous = !previous;
2155 item->m_known = true;
2156//US item = dynamic_cast<KListViewItem *>(item->nextSibling());
2157 item = (KListViewItem *)(item->nextSibling());
2158 }
2159 }
2160 return m_odd;
2161 }
2162 return false;
2163}
2164
2165void KListViewItem::paintCell(QPainter *p, const QColorGroup &cg, int column, int width, int alignment)
2166{
2167 QColorGroup _cg = cg;
2168 const QPixmap *pm = listView()->viewport()->backgroundPixmap();
2169 if (pm && !pm->isNull())
2170 {
2171 _cg.setBrush(QColorGroup::Base, QBrush(backgroundColor(), *pm));
2172 QPoint o = p->brushOrigin();
2173 p->setBrushOrigin( o.x()-listView()->contentsX(), o.y()-listView()->contentsY() );
2174 }
2175 else if (isAlternate()) {
2176//US if (listView()->viewport()->backgroundMode()==Qt::FixedColor)
2177 if (listView()->viewport()->backgroundMode()==QWidget::PaletteBackground)
2178 _cg.setColor(QColorGroup::Background, static_cast< KListView* >(listView())->alternateBackground());
2179 else
2180 _cg.setColor(QColorGroup::Base, static_cast< KListView* >(listView())->alternateBackground());
2181 }
2182 QListViewItem::paintCell(p, _cg, column, width, alignment);
2183}
2184
2185void KListView::virtual_hook( int, void* )
2186{ /*BASE::virtual_hook( id, data );*/ }
2187
2188//US #include "klistview.moc"
2189//US #include "klistviewlineedit.moc"
2190
2191// vim: ts=2 sw=2 et
diff --git a/microkde/kdeui/klistview.h b/microkde/kdeui/klistview.h
new file mode 100644
index 0000000..f7d9f85
--- a/dev/null
+++ b/microkde/kdeui/klistview.h
@@ -0,0 +1,1033 @@
1/* This file is part of the KDE libraries
2 Copyright (C) 2000 Reginald Stadlbauer <reggie@kde.org>
3 Copyright (C) 2000 Charles Samuels <charles@kde.org>
4 Copyright (C) 2000 Peter Putzer <putzer@kde.org>
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License version 2 as published by the Free Software Foundation.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20#ifndef KLISTVIEW_H
21#define KLISTVIEW_H
22
23#include <qlistview.h>
24
25#include <qptrlist.h>
26
27//US
28class QDropEvent;
29class QDragLeaveEvent;
30class QDragMoveEvent;
31class QDragEnterEvent;
32
33class QDragObject;
34class KConfig;
35class KLineEdit;
36/**
37 * This Widget extends the functionality of QListView to honor the system
38 * wide settings for Single Click/Double Click mode, AutoSelection and
39 * ChangeCursorOverLink (TM).
40 *
41 * There is a new signal executed(). It gets connected to either
42 * @ref QListView::clicked() or @ref QListView::doubleClicked() depending on the KDE
43 * wide Single Click/Double Click settings. It is strongly recommended that
44 * you use this signal instead of the above mentioned. This way you dont
45 * need to care about the current settings.
46 * If you want to get informed when the user selects something connect to the
47 * QListView::selectionChanged() signal.
48 *
49 * Drag-and-Drop is supported with the signal @ref #dropped(), just @ref #setAcceptDrops(true)
50 * and connect it to a suitable slot.
51 * To see where you are dropping, @ref setDropVisualizer(true).
52 * And also you'll need @ref acceptDrag(QDropEvent*)
53 *
54 * KListView is drag-enabled, too: to benefit from that you've got derive from it.
55 * Reimplement @ref dragObject() and (possibly) @ref startDrag(),
56 * and @ref setDragEnabled(true).
57 *
58 * @version $Id$
59 */
60class KListView : public QListView
61{
62 Q_OBJECT
63 Q_ENUMS( SelectionModeExt )
64 Q_PROPERTY( bool fullWidth READ fullWidth WRITE setFullWidth )
65 Q_PROPERTY( bool itemsMovable READ itemsMovable WRITE setItemsMovable )
66 Q_PROPERTY( bool itemsRenameable READ itemsRenameable WRITE setItemsRenameable )
67 Q_PROPERTY( bool dragEnabled READ dragEnabled WRITE setDragEnabled )
68 Q_PROPERTY( bool autoOpen READ autoOpen WRITE setAutoOpen )
69 Q_PROPERTY( bool dropVisualizer READ dropVisualizer WRITE setDropVisualizer )
70//US Q_PROPERTY( int tooltipColumn READ tooltipColumn WRITE setTooltipColumn )
71 Q_PROPERTY( int dropVisualizerWidth READ dropVisualizerWidth WRITE setDropVisualizerWidth )
72 Q_PROPERTY( QColor alternateBackground READ alternateBackground WRITE setAlternateBackground )
73
74 Q_OVERRIDE( SelectionModeExt selectionMode READ selectionModeExt WRITE setSelectionModeExt )
75
76public:
77 /**
78 * Possible selection modes.
79 *
80 * The first four correspond directly to QListView::SelectionMode, while
81 * the FileManager selection mode is defined as follows:
82 * @li home: move to the first
83 * @li end: move to the last
84 * @li PgUp/PgDn: move one page up/down
85 * @li up/down: move one item up/down
86 * @li insert: toggle selection of current and move to the next
87 * @li space: toggle selection of the current
88 * @li CTRL+up: move to the previous item and toggle selection of this one
89 * @li CTRL+down: toggle selection of the current item and move to the next
90 * @li CTRL+end: toggle selection from (including) the current
91 * item to (including) the last item
92 * @li CTRL+home: toggle selection from (including) the current
93 * item to the (including) the first item
94 * @li CTRL+PgDn: toggle selection from (including) the current
95 * item to (excluding) the item one page down
96 * @li CTRL+PgUp: toggle selection from (excluding) the current
97 * item to (including) the item one page up
98 *
99 * The combinations work the same with SHIFT instead of CTRL, except
100 * that if you start selecting something using SHIFT everything selected
101 * before will be deselected first.
102 *
103 * Additionally the current item is always selected automatically when
104 * navigating using the keyboard, except other items were selected explicitely.
105 *
106 * This way e.g. SHIFT+up/PgUp then SHIFT+down/PgDn leaves no item selected
107 */
108 enum SelectionModeExt {
109 Single = QListView::Single,
110 Multi = QListView::Multi,
111 Extended = QListView::Extended,
112 NoSelection = QListView::NoSelection,
113 FileManager
114 };
115 void repaintContents( bool erase = true )
116 {
117 QScrollView::repaintContents( contentsX(), contentsY(),
118 visibleWidth(), visibleHeight(), erase );
119 };
120 /**
121 * Constructor.
122 *
123 * The parameters @p parent and @p name are handled by
124 * @ref QListView, as usual.
125 */
126 KListView (QWidget *parent = 0, const char *name = 0);
127
128 /**
129 * Destructor.
130 */
131 virtual ~KListView();
132
133 /**
134 * Reimplemented for internal reasons.
135 * Further reimplementations should call this function or else
136 * some features may not work correctly.
137 *
138 * The API is unaffected.
139 */
140 virtual void setAcceptDrops (bool);
141
142 /**
143 * This function determines whether the given coordinates are within the
144 * execute area. The execute area is the part of a @ref QListViewItem where mouse
145 * clicks or double clicks respectively generate a @ref #executed() signal.
146 * Depending on @ref QListView::allColumnsShowFocus() this is either the
147 * whole item or only the first column.
148 * @return true if point is inside execute area of an item, false in all
149 * other cases including the case that it is over the viewport.
150 */
151 virtual bool isExecuteArea( const QPoint& point );
152
153 /**
154 * Same thing, but from an x coordinate only. This only checks if x is in
155 * the first column (if all columns don't show focus), without testing if
156 * the y coordinate is over an item or not.
157 */
158 bool isExecuteArea( int x );
159
160 /**
161 * @return a list containing the currently selected items.
162 */
163 QPtrList<QListViewItem> selectedItems() const; // ### BIC: KDE 4: use an implicitly shared class! (QValueList?)
164
165 /**
166 * Arbitrarily move @p item to @p parent, positioned immediately after item @p after.
167 */
168 void moveItem(QListViewItem *item, QListViewItem *parent, QListViewItem *after);
169
170 /**
171 * @return the last item (not child!) of this listview.
172 *
173 * @see lastChild()
174 */
175 QListViewItem *lastItem() const;
176
177 /**
178 * @return the last child of this listview.
179 *
180 * @see lastItem()
181 */
182 QListViewItem* lastChild () const;
183
184 /**
185 * @return the lineedit used for inline renaming.
186 * Use that to setup a @ref KCompletion or @ref QValidator for the lineedit
187 *
188 * @since 3.2
189 */
190 KLineEdit* renameLineEdit() const;
191
192 /**
193 * @returns if it is legal to move items in the list view. True by default.
194 *
195 * @see #setDragEnabled()
196 * @see #setItemsMovable()
197 */
198 bool itemsMovable() const;
199
200 /**
201 * @return whether inplace-renaming has been enabled. False by default.
202 *
203 * @see #setItemsRenameable()
204 */
205 bool itemsRenameable() const;
206
207 /**
208 * @return whether dragging is enabled. False by default.
209 *
210 * @see #setDragEnabled()
211 */
212 bool dragEnabled() const;
213
214 /**
215 * @return true if AutoOpen is enabled (not implemented currently).
216 *
217 * @see #setAutoOpen()
218 */
219 bool autoOpen() const;
220
221 /**
222 * @return true if @p column is renamable.
223 *
224 * @see #setRenameable()
225 */
226 bool isRenameable (int column) const;
227
228 /**
229 * @return true if drawing of the drop-visualizer has been enabled. True by default.
230 *
231 * @see #setDropVisualizer()
232 */
233 bool dropVisualizer() const;
234
235 /**
236 * @return the column for which tooltips are displayed (or -1 if none set).
237 *
238 * @see #setTooltipColumn()
239 */
240 int tooltipColumn() const;
241
242 /**
243 * For future expansions.
244 *
245 * Do not use.
246 * @deprecated
247 */
248 bool createChildren() const;
249
250 /**
251 * @return true if drawing of the drop-highlighter has been enabled. False by default.
252 *
253 * @see #setDropHighlighter()
254 */
255 bool dropHighlighter() const;
256
257 /**
258 * The dropVisualizerWidth defaults to 4.
259 *
260 * @see #setDropVisualizerWidth()
261 * @return the current width of the drop-visualizer.
262 */
263 int dropVisualizerWidth () const;
264
265 /**
266 * @return the "extended" selection mode of this listview.
267 *
268 * @see SelectionModeExt
269 * @see setSelectionModeExt
270 */
271 SelectionModeExt selectionModeExt () const;
272
273 /**
274 * Returns the index of @p item within the item tree or -1 if
275 * @p item doesn't exist in this list view. This function takes
276 * all items into account not only the visible ones.
277 */
278 int itemIndex( const QListViewItem *item ) const;
279
280 /**
281 * Returns the item of @p index within the item tree or 0 if
282 * @p index doesn't exist in this list view. This function takes
283 * all items into account not only the visible ones.
284 */
285 QListViewItem* itemAtIndex(int index);
286
287 /**
288 * @deprecated
289 * @see #setFullWidth()
290 */
291 void setFullWidth();
292
293 /**
294 * Let the last column fit exactly all the available width.
295 *
296 * @see #fullWidth()
297 */
298 void setFullWidth(bool fullWidth);
299
300 /**
301 * Returns whether the last column is set to fit the available width.
302 *
303 * @see #setFullWidth()
304 */
305 bool fullWidth() const;
306
307 /**
308 * Reimplemented for full width support
309 *
310 * @see #removeColumn()
311 */
312 virtual int addColumn(const QString& label, int width = -1);
313 /**
314 * Reimplemented for full width support
315 */
316 virtual int addColumn(const QIconSet& iconset, const QString& label, int width = -1);
317 /**
318 * Reimplemented for full width support
319 *
320 * @see #addColumn()
321 */
322 virtual void removeColumn(int index);
323
324 /**
325 * sets the alternate background background color.
326 * This only has an effect if the items are KListViewItems
327 *
328 * @param c the color to use for every other item. Set to an invalid
329 * colour to disable alternate colours.
330 *
331 * @see #alternateBackground()
332 **/
333 void setAlternateBackground(const QColor &c);
334 /**
335 * @return the alternate background color
336 *
337 * @see #setAlternateBackground()
338 */
339 const QColor &alternateBackground() const;
340
341 /**
342 * Saves the list view's layout (column widtsh, column order, sort column)
343 * to a KConfig group
344 *
345 * @param config the @ref KConfig object to write to
346 * @param group the config group to use
347 */
348 void saveLayout(KConfig *config, const QString &group) const;
349 /**
350 * Reads the list view's layout from a KConfig group as stored with
351 * @ref #saveLayout
352 *
353 * @param config the @ref KConfig object to read from
354 * @param group the config group to use
355 */
356 void restoreLayout(KConfig *config, const QString &group);
357 /**
358 * Reimplemented to remember the current sort column and order.
359 * @param column is the column to be sorted, or -1 to sort in order of
360 * insertion
361 * @param whether to sort ascending (or descending)
362 */
363 virtual void setSorting(int column, bool ascending = true);
364
365 /**
366 * @return the currently sorted column, or -1 if none is sorted
367 */
368 int columnSorted(void) const;
369
370 /**
371 * @return whether the current sort is ascending (or descending)
372 */
373 bool ascendingSort(void) const;
374
375signals:
376
377 /**
378 * This signal is emitted whenever the user executes an listview item.
379 * That means depending on the KDE wide Single Click/Double Click
380 * setting the user clicked or double clicked on that item.
381 * @param item is the pointer to the executed listview item.
382 *
383 * Note that you may not delete any @ref QListViewItem objects in slots
384 * connected to this signal.
385 */
386 void executed( QListViewItem *item );
387
388 /**
389 * This signal is emitted whenever the user executes an listview item.
390 * That means depending on the KDE wide Single Click/Double Click
391 * setting the user clicked or double clicked on that item.
392 * @param item is the pointer to the executed listview item.
393 * @param pos is the position where the user has clicked
394 * @param c is the column into which the user clicked.
395 *
396 * Note that you may not delete any @ref QListViewItem objects in slots
397 * connected to this signal.
398 */
399 void executed( QListViewItem *item, const QPoint &pos, int c );
400
401 /**
402 * This signal gets emitted whenever the user double clicks into the
403 * listview.
404 * @param item is the pointer to the clicked listview item.
405 * @param pos is the position where the user has clicked, and
406 * @param c is the column into which the user clicked.
407 *
408 * Note that you may not delete any @ref QListViewItem objects in slots
409 * connected to this signal.
410 *
411 * This signal is more or less here for the sake of completeness.
412 * You should normally not need to use this. In most cases its better
413 * to use @ref #executed() instead.
414 */
415 void doubleClicked( QListViewItem *item, const QPoint &pos, int c );
416
417 /**
418 * This signal gets emitted whenever something acceptable is
419 * dropped onto the listview.
420 *
421 * @param e is the drop event itself (it has already been accepted)
422 * @param after is the item after which the drop occured (or 0L, if
423 * the drop was above all items)
424 *
425 * @see #acceptDrop()
426 */
427 void dropped (QDropEvent * e, QListViewItem *after);
428
429 /**
430 * This signal gets emitted whenever something acceptable is
431 * dropped onto the listview.
432 *
433 * This is an overloaded version of the above (provided to simplify
434 * processing drops outside of the class).
435 *
436 * @param list is the listview
437 * @param e is the drop event itself (it has already been accepted)
438 * @param after is the item after which the drop occured (or 0L, if
439 * the drop was above all items
440 */
441 void dropped (KListView* list, QDropEvent* e, QListViewItem* after);
442
443 /**
444 * This signal gets emitted whenever something acceptable is
445 * dropped onto the listview.
446 *
447 * This function also provides a parent, in the event that your listview
448 * is a tree
449 * @param list is the listview
450 * @param e is the drop event itself (it has already been accepted)
451 * @param parent the item that is to be the parent of the new item
452 * @param after is the item after which the drop occured (or 0L, if
453 * the drop was above all items
454 */
455 void dropped (KListView* list, QDropEvent* e, QListViewItem* parent, QListViewItem* after);
456
457 /**
458 * This signal gets emitted whenever something acceptable is
459 * dropped onto the listview.
460 *
461 * This function also provides a parent, in the event that your listview
462 * is a tree
463 * @param e is the drop event itself (it has already been accepted)
464 * @param parent the item that is to be the parent of the new item
465 * @param after is the item after which the drop occured (or 0L, if
466 * the drop was above all items
467 */
468 void dropped (QDropEvent* e, QListViewItem* parent, QListViewItem* after);
469
470 /**
471 * This signal is emitted when ever the user moves an item in the list via
472 * DnD.
473 * If more than one item is moved at the same time, this signal is only emitted
474 * once.
475 */
476 void moved();
477
478 /**
479 * Connect to this signal if you want to do some preprocessing before
480 * a move is made, for example, to disable sorting
481 *
482 * This is sent only once per each groups of moves. That is, for each
483 * drop that is a move this will be emitted once, before KListView calls
484 * @see moveItem()
485 */
486 void aboutToMove();
487
488 /**
489 * This signal is emitted when ever the user moves an item in the list via
490 * DnD.
491 * If more than one item is moved at the same time, @p afterFirst and
492 * @p afterNow will reflect what was true before the move.
493 * This differs from @ref moved(), so be careful. All the items will have been
494 * moved before @ref moved() is emitted, which is not true in this method. // FIXME
495 * @param item the item that was moved
496 * @param afterFirst the item that parameter item was in before the move, in the list
497 * @param afterNow the item it's currently after.
498 */
499 void moved (QListViewItem *item, QListViewItem *afterFirst, QListViewItem *afterNow);
500
501
502 /**
503 * This signal is emitted after all the items have been moved. It reports info for
504 * each and every item moved, in order. The first element in @p items associates
505 * with the first of afterFirst and afterNow.
506 */
507 void moved(QPtrList<QListViewItem> &items, QPtrList<QListViewItem> &afterFirst, QPtrList<QListViewItem> &afterNow);
508
509 /**
510 * This signal gets emitted when an item is renamed via in-place renaming.
511 *
512 * @param item is the renamed item.
513 * @param str is the new value of column @p col.
514 * @param col is the renamed column.
515 */
516 void itemRenamed(QListViewItem* item, const QString &str, int col);
517
518 /**
519 * Same as above, but without the extra information.
520 */
521 void itemRenamed(QListViewItem* item);
522 void signalDelete();
523
524 /**
525 * This signal is emitted when the shortcut key for popup-menus is pressed.
526 *
527 * Normally you should not use this, just connect a slot to signal
528 * @ref contextMenu (KListView*, QListViewItem*, const QPoint&) to correctly
529 * handle showing context menus regardless of settings.
530 *
531 * @param list is this listview.
532 * @param item is the @ref currentItem() at the time the key was pressed. May be 0L.
533 */
534 void menuShortCutPressed (KListView* list, QListViewItem* item);
535
536 /**
537 * This signal is emitted whenever a context-menu should be shown for item @p i.
538 * It automatically adjusts for all settings involved (Menu key, showMenuOnPress/Click).
539 *
540 * @param l is this listview.
541 * @param i is the item for which the menu should be shown. May be 0L.
542 * @param p is the point at which the menu should be shown.
543 */
544 void contextMenu (KListView* l, QListViewItem* i, const QPoint& p);
545
546public slots:
547 /**
548 * Rename column @p c of @p item.
549 */
550 virtual void rename(QListViewItem *item, int c);
551
552 /**
553 * By default, if you called setItemsRenameable(true),
554 * only the first column is renameable.
555 * Use this function to enable the feature on other columns.
556 *
557 * If you want more intelligent (dynamic) selection,
558 * you'll have to derive from KListView,
559 * and override @ref rename() and call only call it
560 * if you want the item to be renamed.
561 */
562 void setRenameable (int column, bool yesno=true);
563
564 /**
565 * Set whether items in the list view can be moved.
566 * It is enabled by default.
567 *
568 * @see itemsMovable()
569 */
570 virtual void setItemsMovable(bool b);
571
572 /**
573 * Enables inplace-renaming of items.
574 * It is disabled by default.
575 *
576 * @see itemsRenameable()
577 * @see setRenameable()
578 */
579 virtual void setItemsRenameable(bool b);
580
581 /**
582 * Enable/Disable the dragging of items.
583 * It is disabled by default.
584 */
585 virtual void setDragEnabled(bool b);
586
587 /**
588 * Enable/Disable AutoOpen (not implemented currently).
589 */
590 virtual void setAutoOpen(bool b);
591
592 /**
593 * Enable/Disable the drawing of a drop-visualizer
594 * (a bar that shows where a dropped item would be inserted).
595 * It is enabled by default, if dragging is enabled
596 */
597 virtual void setDropVisualizer(bool b);
598
599 /**
600 * Set the width of the (default) drop-visualizer.
601 * If you don't call this method, the width is set to 4.
602 */
603 void setDropVisualizerWidth (int w);
604
605 /**
606 * Set which column should be used for automatic tooltips.
607 *
608 * @param column is the column for which tooltips will be shown.
609 * Set -1 to disable this feature.
610 */
611 virtual void setTooltipColumn(int column);
612
613 /**
614 * Enable/Disable the drawing of a drop-highlighter
615 * (a rectangle around the item under the mouse cursor).
616 * It is disabled by default.
617 */
618 virtual void setDropHighlighter(bool b);
619
620 /**
621 * For future expansions.
622 *
623 * Do not use.
624 * @deprecated
625 */
626 virtual void setCreateChildren(bool b);
627
628 /**
629 * Set the selection mode.
630 *
631 * A different name was chosen to avoid API-clashes with @ref QListView::setSelectionMode().
632 */
633 void setSelectionModeExt (SelectionModeExt mode);
634
635 /**
636 * Enable/disable tabbing between editable cells
637 * @since 3.1
638 */
639 void setTabOrderedRenaming(bool b);
640
641 /**
642 * Returns whether tab ordered renaming is enabled
643 * @since 3.1
644 */
645 bool tabOrderedRenaming() const;
646
647protected:
648 /**
649 * Determine whether a drop on position @p p would count as
650 * being above or below the QRect @p rect.
651 *
652 * @param rect is the rectangle we examine.
653 * @param p is the point located in the rectangle, p is assumed to be in
654 * viewport coordinates.
655 */
656 inline bool below (const QRect& rect, const QPoint& p)
657 {
658 return (p.y() > (rect.top() + (rect.bottom() - rect.top())/2));
659 }
660
661 /**
662 * An overloaded version of below(const QRect&, const QPoint&).
663 *
664 * It differs from the above only in what arguments it takes.
665 *
666 * @param i the item whose rect() is passed to the above function.
667 * @param p is translated from contents coordinates to viewport coordinates
668 * before being passed to the above function.
669 */
670 inline bool below (QListViewItem* i, const QPoint& p)
671 {
672 return below (itemRect(i), contentsToViewport(p));
673 }
674
675 /**
676 * Reimplemented to reload the alternate background in palette changes.
677 * @internal
678 */
679 virtual bool event( QEvent * );
680
681 /**
682 * Emit signal @ref #executed.
683 * @internal
684 */
685 void emitExecute( QListViewItem *item, const QPoint &pos, int c );
686
687 /**
688 * Reimplemented for internal reasons.
689 * Further reimplementations should call this function or else
690 * some features may not work correctly.
691 *
692 * The API is unaffected.
693 */
694 virtual void focusInEvent(QFocusEvent* fe);
695
696 /**
697 * Reimplemented for internal reasons.
698 * Further reimplementations should call this function or else
699 * some features may not work correctly.
700 *
701 * The API is unaffected.
702 */
703 virtual void focusOutEvent( QFocusEvent *fe );
704
705 /**
706 * Reimplemented for internal reasons.
707 * Further reimplementations should call this function or else
708 * some features may not work correctly.
709 *
710 * The API is unaffected.
711 */
712 virtual void leaveEvent( QEvent *e );
713
714 /**
715 * @return the tooltip for @p column of @p item.
716 */
717 virtual QString tooltip(QListViewItem* item, int column) const;
718
719 /**
720 * @return whether the tooltip for @p column of @p item shall be shown at point @p pos.
721 */
722 virtual bool showTooltip(QListViewItem *item, const QPoint &pos, int column) const;
723
724 /**
725 * Reimplemented for internal reasons.
726 * Further reimplementations should call this function or else
727 * some features may not work correctly.
728 *
729 * The API is unaffected.
730 */
731 virtual void contentsDragMoveEvent (QDragMoveEvent *event);
732
733 /**
734 * Reimplemented for internal reasons.
735 * Further reimplementations should call this function or else
736 * some features may not work correctly.
737 *
738 * The API is unaffected.
739 */
740 virtual void contentsMousePressEvent( QMouseEvent *e );
741
742 /**
743 * Reimplemented for internal reasons.
744 * Further reimplementations should call this function or else
745 * some features may not work correctly.
746 *
747 * The API is unaffected.
748 */
749 virtual void contentsMouseMoveEvent( QMouseEvent *e );
750
751 /**
752 * Reimplemented for internal reasons.
753 * Further reimplementations should call this function or else
754 * some features may not work correctly.
755 *
756 * The API is unaffected.
757 */
758 virtual void contentsMouseDoubleClickEvent ( QMouseEvent *e );
759
760 /**
761 * Reimplemented for internal reasons.
762 * Further reimplementations should call this function or else
763 * some features may not work correctly.
764 *
765 * The API is unaffected.
766 */
767 virtual void contentsDragLeaveEvent (QDragLeaveEvent *event);
768
769 /**
770 * Reimplemented for internal reasons.
771 * Further reimplementations should call this function or else
772 * some features may not work correctly.
773 *
774 * The API is unaffected.
775 */
776 virtual void contentsMouseReleaseEvent (QMouseEvent*);
777
778 /**
779 * Reimplemented for internal reasons.
780 * Further reimplementations should call this function or else
781 * some features may not work correctly.
782 *
783 * The API is unaffected.
784 */
785 virtual void contentsDropEvent (QDropEvent*);
786
787 /**
788 * Reimplemented for internal reasons.
789 * Further reimplementations should call this function or else
790 * some features may not work correctly.
791 *
792 * The API is unaffected.
793 */
794 virtual void contentsDragEnterEvent (QDragEnterEvent *);
795
796 /**
797 * @return a dragobject encoding the current selection.
798 *
799 * @see setDragEnabled()
800 */
801 virtual QDragObject *dragObject();
802
803 /**
804 * @return true if the @p event provides some acceptable
805 * format.
806 * A common mistake is to forget the "const" in your reimplementation
807 */
808 virtual bool acceptDrag (QDropEvent* event) const;
809
810 /**
811 * Paint the drag line. If painter is null, don't try to :)
812 *
813 * If after == 0 then the marker should be drawn at the top.
814 *
815 * @return the rectangle that you painted to.
816 */
817 virtual QRect drawDropVisualizer (QPainter *p, QListViewItem *parent, QListViewItem *after);
818
819 /**
820 * Paint the drag rectangle. If painter is null, don't try to :)
821 *
822 *
823 * @return the rectangle that you painted to.
824 */
825 virtual QRect drawItemHighlighter(QPainter *painter, QListViewItem *item);
826
827 /**
828 * This method calls @ref dragObject() and starts the drag.
829 *
830 * Reimplement it to do fancy stuff like setting a pixmap or
831 * using a non-default DragMode
832 */
833 virtual void startDrag();
834
835 /**
836 * Reimplemented for internal reasons.
837 * Further reimplementations should call this function or else
838 * some features may not work correctly.
839 *
840 * The API is unaffected.
841 */
842 virtual void keyPressEvent (QKeyEvent*);
843
844 /**
845 * Reimplemented for internal reasons.
846 * Further reimplementations should call this function or else
847 * some features may not work correctly.
848 *
849 * The API is unaffected.
850 */
851 virtual void viewportPaintEvent(QPaintEvent*);
852
853 /**
854 * In FileManager selection mode: explicitely activate the mode
855 * in which the current item is automatically selected.
856 */
857 void activateAutomaticSelection();
858 /**
859 * In FileManager selection mode: explicitely deactivate the mode
860 * in which the current item is automatically selected.
861 */
862 void deactivateAutomaticSelection();
863 /**
864 * In FileManager selection mode: return whether it is currently in the mode
865 * where the current item is selected automatically.
866 * Returns false if items were selected explicitely, e.g. using the mouse.
867 */
868 bool automaticSelection() const;
869
870 /**
871 * Reimplemented for setFullWidth()
872 */
873 virtual void viewportResizeEvent(QResizeEvent* e);
874
875protected slots:
876 /**
877 * Update internal settings whenever the global ones change.
878 * @internal
879 */
880 void slotSettingsChanged(int);
881
882 void slotMouseButtonClicked( int btn, QListViewItem *item, const QPoint &pos, int c );
883 void doneEditing(QListViewItem *item, int row);
884
885 /**
886 * Repaint the rect where I was drawing the drop line.
887 */
888 void cleanDropVisualizer();
889
890 /**
891 * Repaint the rect where I was drawing the drop rectangle.
892 */
893 void cleanItemHighlighter();
894
895 /**
896 * Emit the @ref contextMenu signal. This slot is for mouse actions.
897 */
898 void emitContextMenu (QListViewItem*, const QPoint&, int);
899
900 /**
901 * Emit the @ref #contextMenu signal. This slot is for key presses.
902 */
903 void emitContextMenu (KListView*, QListViewItem*);
904
905 /**
906 * Accessory slot for AutoSelect
907 * @internal
908 */
909 void slotOnItem( QListViewItem *item );
910
911 /**
912 * Accessory slot for AutoSelect/ChangeCursorOverItem
913 * @internal
914 */
915 void slotOnViewport();
916
917 /**
918 * Process AutoSelection.
919 * @internal
920 */
921 void slotAutoSelect();
922
923 void slotDragExpand();
924
925 /**
926 * Reacts to header changes in full width mode
927 * @internal
928 */
929 void slotHeaderChanged();
930
931protected:
932 /**
933 * Handle dropEvent when itemsMovable() is set to true.
934 */
935 virtual void movableDropEvent (QListViewItem* parent, QListViewItem* afterme);
936
937 /**
938 * Where is the nearest QListViewItem that I'm going to drop?
939 *
940 * FIXME KDE 4.0: Make this method const so it can be called from an
941 * acceptDrag method without ugly casts
942 */
943 virtual void findDrop(const QPoint &pos, QListViewItem *&parent, QListViewItem *&after);
944
945 /**
946 * A special keyPressEvent (for FileManager selection mode).
947 */
948 void fileManagerKeyPressEvent (QKeyEvent*);
949
950 /**
951 * Convert the depth of an item into its indentation in pixels
952 */
953 int depthToPixels( int depth );
954
955private:
956 class Tooltip;
957protected:
958 virtual void virtual_hook( int id, void* data );
959private:
960 class KListViewPrivate;
961 KListViewPrivate *d;
962};
963
964/**
965 * A listview item with support for alternate background colours. It is
966 * a drop-in replacement for @ref QListViewItem
967 *
968 * @short listview item with alternate background colour support
969 */
970class KListViewItem : public QListViewItem
971{
972public:
973 /**
974 * constructors. The semantics remain as in @ref QListViewItem.
975 * Although they accept a @ref QListViewItem as parent, please
976 * don't mix KListViewItem (or subclasses) with QListViewItem
977 * (or subclasses).
978 */
979 KListViewItem(QListView *parent);
980 KListViewItem(QListViewItem *parent);
981 KListViewItem(QListView *parent, QListViewItem *after);
982 KListViewItem(QListViewItem *parent, QListViewItem *after);
983
984 KListViewItem(QListView *parent,
985 QString, QString = QString::null,
986 QString = QString::null, QString = QString::null,
987 QString = QString::null, QString = QString::null,
988 QString = QString::null, QString = QString::null);
989
990 KListViewItem(QListViewItem *parent,
991 QString, QString = QString::null,
992 QString = QString::null, QString = QString::null,
993 QString = QString::null, QString = QString::null,
994 QString = QString::null, QString = QString::null);
995
996 KListViewItem(QListView *parent, QListViewItem *after,
997 QString, QString = QString::null,
998 QString = QString::null, QString = QString::null,
999 QString = QString::null, QString = QString::null,
1000 QString = QString::null, QString = QString::null);
1001
1002 KListViewItem(QListViewItem *parent, QListViewItem *after,
1003 QString, QString = QString::null,
1004 QString = QString::null, QString = QString::null,
1005 QString = QString::null, QString = QString::null,
1006 QString = QString::null, QString = QString::null);
1007
1008 virtual ~KListViewItem();
1009
1010 /**
1011 * retuns true if this item is to be drawn with the alternate background
1012 */
1013 bool isAlternate();
1014 /**
1015 * returns the background colour for this item
1016 */
1017 const QColor &backgroundColor();
1018
1019 virtual void paintCell(QPainter *p, const QColorGroup &cg,
1020 int column, int width, int alignment);
1021
1022private:
1023 void init();
1024
1025private:
1026 uint m_odd : 1;
1027 uint m_known : 1;
1028 uint m_unused : 30;
1029};
1030
1031#endif
1032
1033// vim: ts=2 sw=2 et
diff --git a/microkde/kdeui/kmainwindow.cpp b/microkde/kdeui/kmainwindow.cpp
new file mode 100644
index 0000000..3a2a4d0
--- a/dev/null
+++ b/microkde/kdeui/kmainwindow.cpp
@@ -0,0 +1,994 @@
1 /* This file is part of the KDE libraries
2 Copyright
3 (C) 2000 Reginald Stadlbauer (reggie@kde.org)
4 (C) 1997 Stephan Kulow (coolo@kde.org)
5 (C) 1997-2000 Sven Radej (radej@kde.org)
6 (C) 1997-2000 Matthias Ettrich (ettrich@kde.org)
7 (C) 1999 Chris Schlaeger (cs@kde.org)
8 (C) 2002 Joseph Wenninger (jowenn@kde.org)
9
10 This library is free software; you can redistribute it and/or
11 modify it under the terms of the GNU Library General Public
12 License version 2 as published by the Free Software Foundation.
13
14 This library is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Library General Public License for more details.
18
19 You should have received a copy of the GNU Library General Public License
20 along with this library; see the file COPYING.LIB. If not, write to
21 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22 Boston, MA 02111-1307, USA.
23 */
24#include <qobjectlist.h>
25#include <qstringlist.h>
26#include <qtimer.h>
27#include <qmenubar.h>
28#include <qstatusbar.h>
29#include <qapplication.h>
30
31
32#include "kdebug.h"
33#include "kmainwindow.h"
34#include "kglobalsettings.h"
35#include "kactioncollection.h"
36
37class KMainWindowPrivate {
38public:
39//US bool showHelpMenu:1;
40
41 bool autoSaveSettings:1;
42 bool settingsDirty:1;
43 bool autoSaveWindowSize:1;
44 bool care_about_geometry:1;
45 QString autoSaveGroup;
46//US KAccel * kaccel;
47//US KMainWindowInterface *m_interface;
48 KDEPrivate::ToolBarHandler *toolBarHandler;
49 QTimer* settingsTimer;
50 KToggleAction *showStatusBarAction;
51 QRect defaultWindowSize;
52};
53
54static bool no_query_exit = false;
55
56KMainWindow::KMainWindow( QWidget* parent, const char *name, WFlags f )
57 : QMainWindow( parent, name, f )/*US, KXMLGUIBuilder( this ), helpMenu2( 0 ), factory_( 0 )*/
58{
59 mQToolBar = 0;
60 initKMainWindow(name);
61}
62
63void KMainWindow::parseGeometry(bool parsewidth)
64{
65//US the following code is not getting used in the embedded version !! So disable it for now
66/*US
67
68 assert ( !kapp->geometryArgument().isNull() );
69 assert ( d->care_about_geometry );
70
71#ifndef Q_WS_QWS
72 // FIXME: (E) Implement something similar for Qt Embedded (or decide we don't need it)
73 int x, y;
74 int w, h;
75 int m = XParseGeometry( kapp->geometryArgument().latin1(), &x, &y, (unsigned int*)&w, (unsigned int*)&h);
76 if (parsewidth) {
77 QSize minSize = minimumSize();
78 QSize maxSize = maximumSize();
79 if ( (m & WidthValue) == 0 )
80 w = width();
81 if ( (m & HeightValue) == 0 )
82 h = height();
83 w = QMIN(w,maxSize.width());
84 h = QMIN(h,maxSize.height());
85 w = QMAX(w,minSize.width());
86 h = QMAX(h,minSize.height());
87 resize(w, h);
88 } else {
89 if ( parsewidth && (m & XValue) == 0 )
90 x = geometry().x();
91 if ( parsewidth && (m & YValue) == 0 )
92 y = geometry().y();
93 if ( (m & XNegative) )
94 x = KApplication::desktop()->width() + x - w;
95 if ( (m & YNegative) )
96 y = KApplication::desktop()->height() + y - h;
97 move(x, y);
98 }
99#endif
100*/
101}
102
103KMainWindow::~KMainWindow()
104{
105 delete d->settingsTimer;
106 QMenuBar* mb = internalMenuBar();
107 delete mb;
108//US delete d->m_interface;
109
110 delete d;
111//US memberList->remove( this );
112}
113
114void KMainWindow::initKMainWindow(const char *name)
115{
116 setDockMenuEnabled( FALSE );
117//US mHelpMenu = 0;
118
119//US kapp->setTopWidget( this );
120 actionCollection()->setWidget( this );
121//US connect(kapp, SIGNAL(shutDown()), this, SLOT(shuttingDown()));
122//US if( !memberList )
123//US memberList = new QPtrList<KMainWindow>;
124/*US
125
126 if ( !ksm )
127 ksm = ksmd.setObject(new KMWSessionManaged());
128 // set a unique object name. Required by session management.
129 QCString objname;
130 QCString s;
131 int unusedNumber;
132 if ( !name )
133 { // no name given
134 objname = kapp->instanceName() + "-mainwindow#";
135 s = objname + '1'; // start adding number immediately
136 unusedNumber = 1;
137 }
138 else if( name[ strlen( name ) - 1 ] == '#' )
139 { // trailing # - always add a number
140 objname = name;
141 s = objname + '1'; // start adding number immediately
142 unusedNumber = 1;
143 }
144 else
145 {
146 objname = name;
147 s = objname;
148 unusedNumber = 0; // add numbers only when needed
149 }
150 for(;;) {
151 QWidgetList* list = kapp->topLevelWidgets();
152 QWidgetListIt it( *list );
153 bool found = false;
154 for( QWidget* w = it.current();
155 w != NULL;
156 ++it, w = it.current())
157 if( w != this && w->name() == s )
158 {
159 found = true;
160 break;
161 }
162 delete list;
163 if( !found )
164 break;
165 s.setNum( ++unusedNumber );
166 s = objname + s;
167 }
168 setName( s );
169 memberList->append( this );
170*/
171
172 d = new KMainWindowPrivate;
173//US d->showHelpMenu = true;
174 d->settingsDirty = false;
175 d->autoSaveSettings = false;
176 d->autoSaveWindowSize = true; // for compatibility
177//US d->kaccel = actionCollection()->kaccel();
178 d->toolBarHandler = 0;
179 d->settingsTimer = 0;
180 d->showStatusBarAction = NULL;
181/*US
182 if ((d->care_about_geometry == beeing_first)) {
183 beeing_first = false;
184 if ( kapp->geometryArgument().isNull() ) // if there is no geometry, it doesn't mater
185 d->care_about_geometry = false;
186 else
187 parseGeometry(false);
188 }
189*/
190 d->care_about_geometry = false;
191
192//US setCaption( kapp->caption() );
193 // attach dcop interface
194//US d->m_interface = new KMainWindowInterface(this);
195
196//US if (!kapp->authorize("movable_toolbars"))
197//US setDockWindowsMovable(false);
198}
199
200KAction *KMainWindow::toolBarMenuAction()
201{
202 if ( !d->toolBarHandler )
203 return 0;
204
205 return d->toolBarHandler->toolBarMenuAction();
206}
207
208bool KMainWindow::canBeRestored( int number )
209{
210/*US we do not have and want to save sessioninformation. Use info from the default
211application config.
212*/
213//US if ( !kapp->isRestored() )
214//US return FALSE;
215//US KConfig *config = kapp->sessionConfig();
216 KConfig *config = KGlobal::config();
217 if ( !config )
218 return FALSE;
219 config->setGroup( QString::fromLatin1("Number") );
220 int n = config->readNumEntry( QString::fromLatin1("NumberOfWindows") , 1 );
221 return number >= 1 && number <= n;
222
223}
224
225const QString KMainWindow::classNameOfToplevel( int number )
226{
227/*US we do not have and want to save sessioninformation. Use info from the default
228application config.
229*/
230//US if ( !kapp->isRestored() )
231//US return QString::null;
232//US KConfig *config = kapp->sessionConfig();
233 KConfig *config = KGlobal::config();
234 if ( !config )
235 return QString::null;
236 QString s;
237 s.setNum( number );
238 s.prepend( QString::fromLatin1("WindowProperties") );
239 config->setGroup( s );
240 if ( !config->hasKey( QString::fromLatin1("ClassName") ) )
241 return QString::null;
242 else
243 return config->readEntry( QString::fromLatin1("ClassName") );
244}
245
246bool KMainWindow::restore( int number, bool show )
247{
248/*US we do not have and want to save sessioninformation. Use info from the default
249application config.
250*/
251 if ( !canBeRestored( number ) )
252 return FALSE;
253//US KConfig *config = kapp->sessionConfig();
254 KConfig *config = KGlobal::config();
255
256 if ( readPropertiesInternal( config, number ) ){
257 if ( show )
258 KMainWindow::show();
259 return FALSE;
260 }
261 return FALSE;
262
263}
264
265void KMainWindow::setCaption( const QString &caption )
266{
267//US setPlainCaption( kapp->makeStdCaption(caption) );
268 setPlainCaption( caption );
269}
270
271void KMainWindow::setCaption( const QString &caption, bool modified )
272{
273//US setPlainCaption( kapp->makeStdCaption(caption, true, modified) );
274 setPlainCaption( caption + "modified:" );
275}
276
277void KMainWindow::setPlainCaption( const QString &caption )
278{
279 QMainWindow::setCaption( caption );
280#ifndef Q_WS_QWS
281//US the following is disabled for the embedded version
282//US NETWinInfo info( qt_xdisplay(), winId(), qt_xrootwin(), 0 );
283//US info.setName( caption.utf8().data() );
284#endif
285}
286
287void KMainWindow::slotStateChanged(const QString &newstate)
288{
289 stateChanged(newstate, KXMLGUIClient::StateNoReverse);
290}
291
292/*
293 * Get rid of this for KDE 4.0
294 */
295void KMainWindow::slotStateChanged(const QString &newstate,
296 KXMLGUIClient::ReverseStateChange reverse)
297{
298 stateChanged(newstate, reverse);
299}
300
301void KMainWindow::closeEvent ( QCloseEvent *e )
302{
303 // Save settings if auto-save is enabled, and settings have changed
304 if (d->settingsDirty && d->autoSaveSettings)
305 saveAutoSaveSettings();
306
307 if (queryClose()) {
308 e->accept();
309
310 int not_withdrawn = 0;
311/*US
312 QPtrListIterator<KMainWindow> it(*KMainWindow::memberList);
313 for (it.toFirst(); it.current(); ++it){
314 if ( !it.current()->isHidden() && it.current()->isTopLevel() && it.current() != this )
315 not_withdrawn++;
316 }
317*/
318 if ( !no_query_exit && not_withdrawn <= 0 ) { // last window close accepted?
319/*US
320 if ( queryExit() && !kapp->sessionSaving()) { // Yes, Quit app?
321 // don't call queryExit() twice
322 disconnect(kapp, SIGNAL(shutDown()), this, SLOT(shuttingDown()));
323 kapp->deref(); // ...and quit aplication.
324 } else {
325 // cancel closing, it's stupid to end up with no windows at all....
326 e->ignore();
327 }
328*/
329//US we have no sessionmanagement. Simply close app.
330 if ( queryExit() ) { // Yes, Quit app?
331 qDebug("KMainWindow::closeEvent: Exit application ???");
332 // don't call queryExit() twice
333//US disconnect(kapp, SIGNAL(shutDown()), this, SLOT(shuttingDown()));
334 }
335
336 }
337 }
338}
339
340bool KMainWindow::queryExit()
341{
342 return TRUE;
343}
344
345bool KMainWindow::queryClose()
346{
347 return TRUE;
348}
349
350void KMainWindow::saveGlobalProperties( KConfig* )
351{
352}
353
354void KMainWindow::readGlobalProperties( KConfig* )
355{
356}
357
358void KMainWindow::savePropertiesInternal( KConfig *config, int number )
359{
360 bool oldASWS = d->autoSaveWindowSize;
361 d->autoSaveWindowSize = true; // make saveMainWindowSettings save the window size
362
363 QString s;
364 s.setNum(number);
365 s.prepend(QString::fromLatin1("WindowProperties"));
366 config->setGroup(s);
367
368 // store objectName, className, Width and Height for later restoring
369 // (Only useful for session management)
370 config->writeEntry(QString::fromLatin1("ObjectName"), name());
371 config->writeEntry(QString::fromLatin1("ClassName"), className());
372
373 saveMainWindowSettings(config); // Menubar, statusbar and Toolbar settings.
374
375 s.setNum(number);
376 config->setGroup(s);
377 saveProperties(config);
378
379 d->autoSaveWindowSize = oldASWS;
380}
381
382void KMainWindow::setStandardToolBarMenuEnabled( bool enable )
383{
384 if ( enable )
385 {
386 if ( d->toolBarHandler )
387 return;
388
389 d->toolBarHandler = new KDEPrivate::ToolBarHandler( this );
390
391/*US if ( factory() )
392 factory()->addClient( d->toolBarHandler );
393*/
394 }
395 else
396 {
397 if ( !d->toolBarHandler )
398 return;
399/*US
400 if ( factory() )
401 factory()->removeClient( d->toolBarHandler );
402*/
403 delete d->toolBarHandler;
404 d->toolBarHandler = 0;
405 }
406
407}
408
409bool KMainWindow::isStandardToolBarMenuEnabled() const
410{
411 return ( d->toolBarHandler != 0 );
412}
413
414void KMainWindow::createStandardStatusBarAction(){
415 if(!d->showStatusBarAction){
416 d->showStatusBarAction = KStdAction::showStatusbar(this, SLOT(setSettingsDirty()), actionCollection());
417 connect(d->showStatusBarAction, SIGNAL(toggled(bool)), statusBar(), SLOT(setShown(bool)));
418 if(internalStatusBar())
419 d->showStatusBarAction->setChecked(!internalStatusBar()->isHidden());
420 }
421}
422
423QToolBar *KMainWindow::tBar( )
424{
425 if ( ! mQToolBar )
426 mQToolBar = new QToolBar( this );
427 return mQToolBar;
428}
429
430KToolBar *KMainWindow::toolBar( const char * name )
431{
432
433 if (!name)
434 name = "mainToolBar";
435 KToolBar *tb = (KToolBar*)child( name, "KToolBar" );
436 if ( tb )
437 return tb;
438 bool honor_mode = (name == "mainToolBar");
439
440/*US
441 if ( builderClient() )
442 return new KToolBar(this, name, honor_mode); // XMLGUI constructor
443 else
444*/
445 return new KToolBar(this, Top, false, name, honor_mode ); // non-XMLGUI
446}
447
448QPtrListIterator<KToolBar> KMainWindow::toolBarIterator()
449{
450 toolbarList.clear();
451 QPtrList<QToolBar> lst;
452 for ( int i = (int)QMainWindow::Unmanaged; i <= (int)Minimized; ++i ) {
453 lst = toolBars( (ToolBarDock)i );
454 for ( QToolBar *tb = lst.first(); tb; tb = lst.next() ) {
455 if ( !tb->inherits( "KToolBar" ) )
456 continue;
457 toolbarList.append( (KToolBar*)tb );
458 }
459 }
460 return QPtrListIterator<KToolBar>( toolbarList );
461}
462
463void KMainWindow::setAutoSaveSettings( const QString & groupName, bool saveWindowSize )
464{
465 d->autoSaveSettings = true;
466 d->autoSaveGroup = groupName;
467 d->autoSaveWindowSize = saveWindowSize;
468 // Get notified when the user moves a toolbar around
469//US connect( this, SIGNAL( dockWindowPositionChanged( QDockWindow * ) ),
470//US this, SLOT( setSettingsDirty() ) );
471 connect( this, SIGNAL( toolBarPositionChanged(QToolBar *) ),
472 this, SLOT( setSettingsDirty() ) );
473
474
475 // Get default values
476//US int scnum = QApplication::desktop()->screenNumber(parentWidget());
477//US QRect desk = QApplication::desktop()->screenGeometry(scnum);
478 QRect desk = KGlobalSettings::desktopGeometry(0);
479
480 d->defaultWindowSize = QRect(desk.width(), width(), desk.height(), height());
481 // Now read the previously saved settings
482 applyMainWindowSettings( KGlobal::config(), groupName );
483}
484
485
486void KMainWindow::resetAutoSaveSettings()
487{
488 d->autoSaveSettings = false;
489 if ( d->settingsTimer )
490 d->settingsTimer->stop();
491}
492
493bool KMainWindow::autoSaveSettings() const
494{
495 return d->autoSaveSettings;
496}
497
498QString KMainWindow::autoSaveGroup() const
499{
500 return d->autoSaveGroup;
501}
502
503void KMainWindow::saveAutoSaveSettings()
504{
505 ASSERT( d->autoSaveSettings );
506 //kdDebug(200) << "KMainWindow::saveAutoSaveSettings -> saving settings" << endl;
507 saveMainWindowSettings( KGlobal::config(), d->autoSaveGroup );
508 KGlobal::config()->sync();
509 d->settingsDirty = false;
510 if ( d->settingsTimer )
511 d->settingsTimer->stop();
512}
513
514void KMainWindow::createGUI( const QString &xmlfile, bool _conserveMemory )
515{
516 // disabling the updates prevents unnecessary redraws
517 setUpdatesEnabled( false );
518
519 // just in case we are rebuilding, let's remove our old client
520//US guiFactory()->removeClient( this );
521
522 // make sure to have an empty GUI
523 QMenuBar* mb = internalMenuBar();
524 if ( mb )
525 mb->clear();
526
527 (void)toolBarIterator(); // make sure toolbarList is most-up-to-date
528 toolbarList.setAutoDelete( true );
529 toolbarList.clear();
530 toolbarList.setAutoDelete( false );
531/*US
532 // don't build a help menu unless the user ask for it
533 if (d->showHelpMenu) {
534 // we always want a help menu
535 if (helpMenu2 == 0)
536 helpMenu2 = new KHelpMenu(this, instance()->aboutData(), true,
537 actionCollection());
538 }
539
540 // we always want to load in our global standards file
541 setXMLFile( locate( "config", "ui/ui_standards.rc", instance() ) );
542
543 // now, merge in our local xml file. if this is null, then that
544 // means that we will be only using the global file
545 if ( !xmlfile.isNull() ) {
546 setXMLFile( xmlfile, true );
547 } else {
548 QString auto_file(instance()->instanceName() + "ui.rc");
549 setXMLFile( auto_file, true );
550 }
551
552 // make sure we don't have any state saved already
553 setXMLGUIBuildDocument( QDomDocument() );
554
555 // do the actual GUI building
556 guiFactory()->addClient( this );
557
558 // try and get back *some* of our memory
559 if ( _conserveMemory )
560 {
561 // before freeing the memory allocated by the DOM document we also
562 // free all memory allocated internally in the KXMLGUIFactory for
563 // the menubar and the toolbars . This however implies that we
564 // have to take care of deleting those widgets ourselves. For
565 // destruction this is no problem, but when rebuilding we have
566 // to take care of that (and we want to rebuild the GUI when
567 // using stuff like the toolbar editor ).
568 // In addition we have to take care of not removing containers
569 // like popupmenus, defined in the XML document.
570 // this code should probably go into a separate method in KMainWindow.
571 // there's just one problem: I'm bad in finding names ;-) , so
572 // I skipped this ;-)
573
574 QDomDocument doc = domDocument();
575
576 QDomElement e = doc.documentElement().firstChild().toElement();
577 for (; !e.isNull(); e = e.nextSibling().toElement() ) {
578 if ( e.tagName().lower() == "toolbar" )
579 factory_->resetContainer( e.attribute( "name" ) );
580 else if ( e.tagName().lower() == "menubar" )
581 factory_->resetContainer( e.tagName(), true );
582 }
583
584 conserveMemory();
585 }
586*/
587 setUpdatesEnabled( true );
588 updateGeometry();
589}
590
591void KMainWindow::saveMainWindowSettings(KConfig *config, const QString &configGroup)
592{
593 kdDebug(200) << "KMainWindow::saveMainWindowSettings " << configGroup << endl;
594//US QStrList entryList;
595 QStringList entryList;
596 QString oldGroup;
597
598 if (!configGroup.isEmpty())
599 {
600 oldGroup = config->group();
601 config->setGroup(configGroup);
602 }
603
604 // Called by session management - or if we want to save the window size anyway
605 if ( d->autoSaveWindowSize )
606 saveWindowSize( config );
607
608 QStatusBar* sb = internalStatusBar();
609 if (sb) {
610 entryList.clear();
611 if ( sb->isHidden() )
612 entryList.append("Disabled");
613 else
614 entryList.append("Enabled");
615
616 if(sb->isHidden())
617 //US config->writeEntry(QString::fromLatin1("StatusBar"), entryList, ';');
618 config->writeEntry(QString::fromLatin1("StatusBar"), entryList);
619 else
620 config->deleteEntry(QString::fromLatin1("StatusBar"));
621 }
622
623 QMenuBar* mb = internalMenuBar();
624 if (mb) {
625 entryList.clear();
626 if ( mb->isHidden() )
627 entryList.append("Disabled");
628 else
629 entryList.append("Enabled");
630
631 // By default we don't hide.
632 if(mb->isHidden())
633 //US config->writeEntry(QString::fromLatin1("MenuBar"), entryList, ';');
634 config->writeEntry(QString::fromLatin1("MenuBar"), entryList);
635 else
636 config->deleteEntry(QString::fromLatin1("MenuBar"));
637 }
638
639 int n = 1; // Toolbar counter. toolbars are counted from 1,
640 KToolBar *toolbar = 0;
641 QPtrListIterator<KToolBar> it( toolBarIterator() );
642 while ( ( toolbar = it.current() ) ) {
643 ++it;
644 QString group;
645 if (!configGroup.isEmpty())
646 {
647 // Give a number to the toolbar, but prefer a name if there is one,
648 // because there's no real guarantee on the ordering of toolbars
649 group = (!::qstrcmp(toolbar->name(), "unnamed") ? QString::number(n) : QString(" ")+toolbar->name());
650 group.prepend(" Toolbar");
651 group.prepend(configGroup);
652 }
653 toolbar->saveSettings(config, group);
654 n++;
655 }
656 if (!configGroup.isEmpty())
657 config->setGroup(oldGroup);
658}
659
660bool KMainWindow::readPropertiesInternal( KConfig *config, int number )
661{
662 if ( number == 1 )
663 readGlobalProperties( config );
664
665 // in order they are in toolbar list
666 QString s;
667 s.setNum(number);
668 s.prepend(QString::fromLatin1("WindowProperties"));
669
670 config->setGroup(s);
671
672 // restore the object name (window role)
673 if ( config->hasKey(QString::fromLatin1("ObjectName" )) )
674 setName( config->readEntry(QString::fromLatin1("ObjectName")).latin1()); // latin1 is right here
675
676 applyMainWindowSettings(config); // Menubar, statusbar and toolbar settings.
677
678 s.setNum(number);
679 config->setGroup(s);
680 readProperties(config);
681 return true;
682}
683
684void KMainWindow::applyMainWindowSettings(KConfig *config, const QString &configGroup)
685{
686 kdDebug(200) << "KMainWindow::applyMainWindowSettings" << endl;
687 QString entry;
688//US QStrList entryList;
689 QStringList entryList;
690 int i = 0; // Number of entries in list
691
692 if (!configGroup.isEmpty())
693 config->setGroup(configGroup);
694
695 restoreWindowSize(config);
696
697 QStatusBar* sb = internalStatusBar();
698 if (sb) {
699 entryList.clear();
700//US i = config->readListEntry (QString::fromLatin1("StatusBar"), entryList, ';');
701 entryList = config->readListEntry (QString::fromLatin1("StatusBar"));
702 entry = entryList.first();
703 if (entry == QString::fromLatin1("Disabled"))
704 sb->hide();
705 else
706 sb->show();
707 if(d->showStatusBarAction)
708 d->showStatusBarAction->setChecked(!sb->isHidden());
709 }
710
711 QMenuBar* mb = internalMenuBar();
712 if (mb) {
713 entryList.clear();
714//US i = config->readListEntry (QString::fromLatin1("MenuBar"), entryList, ';');
715 entryList = config->readListEntry (QString::fromLatin1("MenuBar"));
716 entry = entryList.first();
717 if (entry==QString::fromLatin1("Disabled"))
718 {
719 mb->hide();
720 } else
721 {
722 mb->show();
723 }
724 }
725
726 int n = 1; // Toolbar counter. toolbars are counted from 1,
727 KToolBar *toolbar;
728 QPtrListIterator<KToolBar> it( toolBarIterator() ); // must use own iterator
729
730 for ( ; it.current(); ++it) {
731 toolbar= it.current();
732 QString group;
733 if (!configGroup.isEmpty())
734 {
735 // Give a number to the toolbar, but prefer a name if there is one,
736 // because there's no real guarantee on the ordering of toolbars
737 group = (!::qstrcmp(toolbar->name(), "unnamed") ? QString::number(n) : QString(" ")+toolbar->name());
738 group.prepend(" Toolbar");
739 group.prepend(configGroup);
740 }
741 toolbar->applySettings(config, group);
742 n++;
743 }
744
745 finalizeGUI( true );
746 }
747
748void KMainWindow::finalizeGUI( bool force )
749{
750 //kdDebug(200) << "KMainWindow::finalizeGUI force=" << force << endl;
751 // The whole reason for this is that moveToolBar relies on the indexes
752 // of the other toolbars, so in theory it should be called only once per
753 // toolbar, but in increasing order of indexes.
754 // Since we can't do that immediately, we move them, and _then_
755 // we call positionYourself again for each of them, but this time
756 // the toolbariterator should give them in the proper order.
757 // Both the XMLGUI and applySettings call this, hence "force" for the latter.
758 QPtrListIterator<KToolBar> it( toolBarIterator() );
759 for ( ; it.current() ; ++ it )
760 it.current()->positionYourself( force );
761
762 d->settingsDirty = false;
763}
764
765void KMainWindow::saveWindowSize( KConfig * config ) const
766{
767/*US
768 int scnum = QApplication::desktop()->screenNumber(parentWidget());
769 QRect desk = QApplication::desktop()->screenGeometry(scnum);
770*/
771 QRect desk = KGlobalSettings::desktopGeometry(0);
772
773 QRect size( desk.width(), width(), desk.height(), height() );
774 if(size != d->defaultWindowSize){
775 config->writeEntry(QString::fromLatin1("Width %1").arg(desk.width()), width() );
776 config->writeEntry(QString::fromLatin1("Height %1").arg(desk.height()), height() );
777 }
778 else{
779 config->deleteEntry(QString::fromLatin1("Width %1").arg(desk.width()));
780 config->deleteEntry(QString::fromLatin1("Height %1").arg(desk.height()));
781 }
782}
783
784void KMainWindow::restoreWindowSize( KConfig * config )
785{
786 if (d->care_about_geometry) {
787 parseGeometry(true);
788 } else {
789 // restore the size
790/*US int scnum = QApplication::desktop()->screenNumber(parentWidget());
791 QRect desk = QApplication::desktop()->screenGeometry(scnum);
792*/
793 QRect desk = KGlobalSettings::desktopGeometry(0);
794
795 QSize size( config->readNumEntry( QString::fromLatin1("Width %1").arg(desk.width()), 0 ),
796 config->readNumEntry( QString::fromLatin1("Height %1").arg(desk.height()), 0 ) );
797 if (size.isEmpty()) {
798 // try the KDE 2.0 way
799 size = QSize( config->readNumEntry( QString::fromLatin1("Width"), 0 ),
800 config->readNumEntry( QString::fromLatin1("Height"), 0 ) );
801 if (!size.isEmpty()) {
802 // make sure the other resolutions don't get old settings
803 config->writeEntry( QString::fromLatin1("Width"), 0 );
804 config->writeEntry( QString::fromLatin1("Height"), 0 );
805 }
806 }
807 if ( !size.isEmpty() )
808 resize( size );
809 }
810}
811
812bool KMainWindow::initialGeometrySet() const
813{
814 return d->care_about_geometry;
815}
816
817void KMainWindow::ignoreInitialGeometry()
818{
819 d->care_about_geometry = false;
820}
821
822void KMainWindow::setSettingsDirty()
823{
824 //kdDebug(200) << "KMainWindow::setSettingsDirty" << endl;
825 d->settingsDirty = true;
826 if ( d->autoSaveSettings )
827 {
828 // Use a timer to save "immediately" user-wise, but not too immediately
829 // (to compress calls and save only once, in case of multiple changes)
830 if ( !d->settingsTimer )
831 {
832 d->settingsTimer = new QTimer( this );
833 connect( d->settingsTimer, SIGNAL( timeout() ), SLOT( saveAutoSaveSettings() ) );
834 }
835 d->settingsTimer->start( 500, true );
836 }
837}
838
839bool KMainWindow::settingsDirty() const
840{
841 return d->settingsDirty;
842}
843
844QString KMainWindow::settingsGroup() const
845{
846 return d->autoSaveGroup;
847}
848
849void KMainWindow::resizeEvent( QResizeEvent * )
850{
851 if ( d->autoSaveWindowSize )
852 setSettingsDirty();
853}
854
855bool KMainWindow::hasMenuBar()
856{
857 return (internalMenuBar());
858}
859
860//US KMenuBar *KMainWindow::menuBar()
861QMenuBar *KMainWindow::menuBar()
862{
863//US KMenuBar * mb = internalMenuBar();
864 QMenuBar * mb = internalMenuBar();
865 if ( !mb ) {
866//US mb = new KMenuBar( this );
867 mb = new QMenuBar( this );
868 // trigger a re-layout and trigger a call to the private
869 // setMenuBar method.
870 QMainWindow::menuBar();
871 }
872 return mb;
873}
874
875//US KStatusBar *KMainWindow::statusBar()
876QStatusBar *KMainWindow::statusBar()
877{
878//US KStatusBar * sb = internalStatusBar();
879 QStatusBar * sb = internalStatusBar();
880 if ( !sb ) {
881//US sb = new KStatusBar( this );
882 sb = new QStatusBar( this );
883 // trigger a re-layout and trigger a call to the private
884 // setStatusBar method.
885 QMainWindow::statusBar();
886 }
887 return sb;
888}
889
890void KMainWindow::shuttingDown()
891{
892 // Needed for Qt <= 3.0.3 at least to prevent reentrancy
893 // when queryExit() shows a dialog. Check before removing!
894 static bool reentrancy_protection = false;
895 if (!reentrancy_protection)
896 {
897 reentrancy_protection = true;
898 // call the virtual queryExit
899 queryExit();
900 reentrancy_protection = false;
901 }
902
903}
904
905//US KMenuBar *KMainWindow::internalMenuBar()
906QMenuBar *KMainWindow::internalMenuBar()
907{
908//US QObjectList *l = queryList( "KMenuBar", 0, false, false );
909 QObjectList *l = queryList( "QMenuBar", 0, false, false );
910 if ( !l || !l->first() ) {
911 delete l;
912 return 0;
913 }
914
915//US KMenuBar *m = (KMenuBar*)l->first();
916 QMenuBar *m = (QMenuBar*)l->first();
917 delete l;
918 return m;
919}
920
921//US KStatusBar *KMainWindow::internalStatusBar()
922QStatusBar *KMainWindow::internalStatusBar()
923{
924//US QObjectList *l = queryList( "KStatusBar", 0, false, false );
925 QObjectList *l = queryList( "QStatusBar", 0, false, false );
926 if ( !l || !l->first() ) {
927 delete l;
928 return 0;
929 }
930
931//US KStatusBar *s = (KStatusBar*)l->first();
932 QStatusBar *s = (QStatusBar*)l->first();
933 delete l;
934 return s;
935}
936
937void KMainWindow::childEvent( QChildEvent* e)
938{
939 QMainWindow::childEvent( e );
940}
941
942void KMainWindow::paintEvent( QPaintEvent * )
943{
944 // do nothing
945}
946
947QSize KMainWindow::sizeForCentralWidgetSize(QSize size)
948{
949 KToolBar *tb = (KToolBar*)child( "mainToolBar", "KToolBar" );
950 if (tb && !tb->isHidden()) {
951 switch( tb->barPos() )
952 {
953 case KToolBar::Top:
954 case KToolBar::Bottom:
955 size += QSize(0, tb->sizeHint().height());
956 break;
957
958 case KToolBar::Left:
959 case KToolBar::Right:
960 size += QSize(toolBar()->sizeHint().width(), 0);
961 break;
962
963 case KToolBar::Flat:
964//US size += QSize(0, 3+kapp->style().pixelMetric( QStyle::PM_DockWindowHandleExtent ));
965 size += QSize(0, tb->sizeHint().height());
966 break;
967
968 default:
969 break;
970 }
971 }
972//US KMenuBar *mb = menuBar();
973 QMenuBar *mb = menuBar();
974 if (!mb->isHidden()) {
975 size += QSize(0,mb->heightForWidth(size.width()));
976/*US if (style().styleHint(QStyle::SH_MainWindow_SpaceBelowMenuBar, this))
977 size += QSize( 0, dockWindowsMovable() ? 1 : 2);
978*/
979 size += QSize( 0, 2);
980 }
981 QStatusBar *sb = internalStatusBar();
982 if( sb && !sb->isHidden() )
983 size += QSize(0, sb->sizeHint().height());
984
985 return size;
986}
987
988// why do we support old gcc versions? using KXMLGUIBuilder::finalizeGUI;
989void KMainWindow::finalizeGUI( KXMLGUIClient *client )
990{ /*US KXMLGUIBuilder::finalizeGUI( client );*/ }
991
992void KMainWindow::virtual_hook( int id, void* data )
993{ /*US KXMLGUIBuilder::virtual_hook( id, data );*/
994 KXMLGUIClient::virtual_hook( id, data ); }
diff --git a/microkde/kdeui/kmainwindow.h b/microkde/kdeui/kmainwindow.h
new file mode 100644
index 0000000..e76e732
--- a/dev/null
+++ b/microkde/kdeui/kmainwindow.h
@@ -0,0 +1,776 @@
1/*
2 This file is part of the KDE libraries
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License version 2 as published by the Free Software Foundation.
7
8 This library is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 Library General Public License for more details.
12
13 You should have received a copy of the GNU Library General Public License
14 along with this library; see the file COPYING.LIB. If not, write to
15 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16 Boston, MA 02111-1307, USA.
17
18 $Id$
19
20*/
21
22
23
24#ifndef KMAINWINDOW_H
25#define KMAINWINDOW_H
26
27/*US
28#include "kxmlguifactory.h"
29#include "kxmlguiclient.h"
30#include "kxmlguibuilder.h"
31#include <qmetaobject.h>
32
33class KPopupMenu;
34class KXMLGUIFactory;
35class KConfig;
36class KHelpMenu;
37class KStatusBar;
38class QStatusBar;
39class KMenuBar;
40class KMWSessionManaged;
41class KAccel;
42class KToolBarMenuAction;
43*/
44
45class QMenuBar;
46class QStatusBar;
47class KMainWindowPrivate;
48class KAction;
49
50#include <ktoolbar.h>
51#include <ktoolbarhandler.h>
52#include <kxmlguiclient.h>
53#include <qmainwindow.h>
54#include <qptrlist.h>
55
56class KActionCollection;
57
58class KMainWindow : public QMainWindow, virtual public KXMLGUIClient
59{
60 Q_OBJECT
61
62private:
63//US create private defaultconstructor
64 KMainWindow() {;};
65
66public:
67public:
68 /**
69 * Construct a main window.
70 *
71 * @param parent The widget parent. This is usually 0 but it may also be the window
72 * group leader. In that case, the KMainWindow becomes sort of a
73 * secondary window.
74 *
75 * @param name The object name. For session management and window management to work
76 * properly, all main windows in the application should have a
77 * different name. When passing 0 (the default), KMainWindow will create
78 * a unique name, but it's recommended to explicitly pass a window name that will
79 * also describe the type of the window. If there can be several windows of the same
80 * type, append '#' (hash) to the name, and KMainWindow will append numbers to make
81 * the names unique. For example, for a mail client which has one main window showing
82 * the mails and folders, and which can also have one or more windows for composing
83 * mails, the name for the folders window should be e.g. "mainwindow" and
84 * for the composer windows "composer#".
85 *
86 * @param f Specify the widget flags. The default is
87 * WType_TopLevel and WDestructiveClose. TopLevel indicates that a
88 * main window is a toplevel window, regardless of whether it has a
89 * parent or not. DestructiveClose indicates that a main window is
90 * automatically destroyed when its window is closed. Pass 0 if
91 * you do not want this behavior.
92 *
93 * KMainWindows must be created on the heap with 'new', like:
94 * <pre> KMainWindow *kmw = new KMainWindow (...</pre>
95 **/
96 KMainWindow( QWidget* parent = 0, const char *name = 0, WFlags f = WType_TopLevel | WDestructiveClose );
97
98
99 /**
100 * Destructor.
101 *
102 * Will also destroy the toolbars, and menubar if
103 * needed.
104 */
105 virtual ~KMainWindow();
106
107 /**
108 * Retrieve the standard help menu.
109 *
110 * It contains entires for the
111 * help system (activated by F1), an optional "What's This?" entry
112 * (activated by Shift F1), an application specific dialog box,
113 * and an "About KDE" dialog box.
114 *
115 * Example (adding a standard help menu to your application):
116 * <pre>
117 * KPopupMenu *help = helpMenu( <myTextString> );
118 * menuBar()->insertItem( i18n("&Help"), help );
119 * </pre>
120 *
121 * @param aboutAppText The string that is used in the application
122 * specific dialog box. If you leave this string empty the
123 * information in the global @ref KAboutData of the
124 * application will be used to make a standard dialog box.
125 *
126 * @param showWhatsThis Set this to false if you do not want to include
127 * the "What's This" menu entry.
128 *
129 * @return A standard help menu.
130 */
131//US KPopupMenu* helpMenu( const QString &aboutAppText = QString::null,
132//US bool showWhatsThis = TRUE );
133
134 /**
135 * Returns the help menu. Creates a standard help menu if none exists yet.
136 *
137 * It contains entries for the
138 * help system (activated by F1), an optional "What's This?" entry
139 * (activated by Shift F1), an application specific dialog box,
140 * and an "About KDE" dialog box. You must create the application
141 * specific dialog box yourself. When the "About application"
142 * menu entry is activated, a signal will trigger the
143 * @ref showAboutApplication slot. See @ref showAboutApplication for more
144 * information.
145 *
146 * Example (adding a help menu to your application):
147 * <pre>
148 * menuBar()->insertItem( i18n("&Help"), customHelpMenu() );
149 * </pre>
150 *
151 * @param showWhatsThis Set this to @p false if you do not want to include
152 * the "What's This" menu entry.
153 *
154 * @return A standard help menu.
155 */
156//US KPopupMenu* customHelpMenu( bool showWhatsThis = TRUE );
157
158 /**
159 * @sect Session Management
160 *
161 * Try to restore the toplevel widget as defined by the number (1..X).
162 *
163 * If the session did not contain so high a number, the configuration
164 * is not changed and @p false returned.
165 *
166 * That means clients could simply do the following:
167 * <pre>
168 * if (kapp->isRestored()){
169 * int n = 1;
170 * while (KMainWindow::canBeRestored(n)){
171 * (new childMW)->restore(n);
172 * n++;
173 * }
174 * } else {
175 * // create default application as usual
176 * }
177 * </pre>
178 * Note that @ref QWidget::show() is called implicitly in restore.
179 *
180 * With this you can easily restore all toplevel windows of your
181 * application.
182 *
183 * If your application uses different kinds of toplevel
184 * windows, then you can use @ref KMainWindow::classNameOfToplevel(n)
185 * to determine the exact type before calling the childMW
186 * constructor in the example from above.
187 *
188 * If your client has only one kind of toplevel widgets (which
189 * should be pretty usual) then you should use the RESTORE-macro
190 * for backwards compatibility with 3.1 and 3.0 branches:
191 *
192 * <pre>
193 * if (kapp->isRestored())
194 * RESTORE(childMW)
195 * else {
196 * // create default application as usual
197 * }
198 * </pre>
199 *
200 * The macro expands to the term above but is easier to use and
201 * less code to write.
202 *
203 * For new code or if you have more than one kind of toplevel
204 * widget (each derived from @ref KMainWindow, of course), you can
205 * use the templated @ref kRestoreMainWindows global functions:
206 *
207 * <pre>
208 * if (kapp->isRestored())
209 * kRestoreMainWindows< childMW1, childMW2, childMW3 >();
210 * else {
211 * // create default application as usual
212 * }
213 * </pre>
214 *
215 * Currently, these functions are provided for up to three
216 * template arguments. If you need more, tell us. To help you in
217 * deciding whether or not you can use @ref kRestoreMainWindows, a
218 * define KDE_RESTORE_MAIN_WINDOWS_NUM_TEMPLATE_ARGS is provided.
219 *
220 * @see restore()
221 * @see classNameOfToplevel()
222 *
223 **/
224 static bool canBeRestored( int number );
225
226 /**
227 * Returns the @ref className() of the @p number of the toplevel window which
228 * should be restored.
229 *
230 * This is only useful if your application uses
231 * different kinds of toplevel windows.
232 */
233 static const QString classNameOfToplevel( int number );
234
235 /**
236 * Restore the session specified by @p number.
237 *
238 * Returns @p false if this
239 * fails, otherwise returns @p true and shows the window.
240 * You should call @ref canBeRestored() first.
241 * If @p show is true (default), this widget will be shown automatically.
242 */
243 bool restore( int number, bool show = TRUE );
244
245//US virtual KXMLGUIFactory *guiFactory();
246
247 /**
248 * Create a GUI given a local XML file.
249 *
250 * If @p xmlfile is NULL,
251 * then it will try to construct a local XML filename like
252 * appnameui.rc where 'appname' is your app's name. If that file
253 * does not exist, then the XML UI code will only use the global
254 * (standard) XML file for the layout purposes.
255 *
256 * Note that when passing true for the conserveMemory argument subsequent
257 * calls to guiFactory()->addClient/removeClient may not work as expected.
258 * Also retrieving references to containers like popup menus or toolbars using
259 * the container method will not work.
260 *
261 * @param xmlfile The local xmlfile (relative or absolute)
262 * @param _conserveMemory Specify whether createGUI() should call
263 * @ref KXMLGuiClient::conserveMemory() to free all memory
264 * allocated by the @ref QDomDocument and by the KXMLGUIFactory.
265 */
266 void createGUI( const QString &xmlfile = QString::null, bool _conserveMemory = TRUE );
267
268 /**
269 * Enables the build of a standard help menu when calling createGUI().
270 *
271 * The default behavior is to build one, you must call this function
272 * to disable it
273 */
274 void setHelpMenuEnabled(bool showHelpMenu = true);
275
276 /**
277 * Return @p true when the help menu is enabled
278 */
279 bool isHelpMenuEnabled();
280
281
282 /**
283 * Returns true, if there is a menubar
284 * @since 3.1
285 */
286 bool hasMenuBar();
287
288 /**
289 * Returns a pointer to the menu bar.
290 *
291 * If there is no menu bar yet one will be created.
292 **/
293//US KMenuBar *menuBar();
294 QMenuBar *menuBar();
295
296 /**
297 * Returns a pointer to the status bar.
298 *
299 * If there is no
300 * status bar yet one will be created.
301 */
302//US KStatusBar *statusBar();
303 QStatusBar *statusBar();
304
305 /**
306 * List of members of KMainWindow class.
307 */
308//US static QPtrList<KMainWindow>* memberList;
309
310 /**
311 * Returns a pointer to the toolbar with the specified name.
312 * This refers to toolbars created dynamically from the XML UI
313 * framework. If the toolbar does not exist one will be created.
314 *
315 * @param name The internal name of the toolbar. If no name is
316 * specified "mainToolBar" is assumed.
317 *
318 * @return A pointer to the toolbar
319 **/
320 KToolBar *toolBar( const char *name=0 );
321 // method for getting rid of KDE-Crap
322 QToolBar *tBar( );
323
324 /**
325 * @return An iterator over the list of all toolbars for this window.
326 */
327 QPtrListIterator<KToolBar> toolBarIterator();
328
329 /**
330 * @return A KAccel instance bound to this mainwindow. Used automatically
331 * by KAction to make keybindings work in all cases.
332 */
333 KAccel *accel();
334
335 void setFrameBorderWidth( int ) {}
336
337 /**
338 * Call this to enable "auto-save" of toolbar/menubar/statusbar settings
339 * (and optionally window size).
340 * If the *bars were moved around/shown/hidden when the window is closed,
341 * saveMainWindowSettings( KGlobal::config(), groupName ) will be called.
342 *
343 * @param groupName a name that identifies this "type of window".
344 * You can have several types of window in the same application.
345 *
346 * @param saveWindowSize set it to true to include the window size
347 * when saving.
348 *
349 * Typically, you will call setAutoSaveSettings() in your
350 * KMainWindow-inherited class constructor, and it will take care
351 * of restoring and saving automatically. Make sure you call this
352 * _after all_ your *bars have been created.
353 */
354 void setAutoSaveSettings( const QString & groupName = QString::fromLatin1("MainWindow"),
355 bool saveWindowSize = true );
356
357 /**
358 * Disable the auto-save-settings feature.
359 * You don't normally need to call this, ever.
360 */
361 void resetAutoSaveSettings();
362
363 /**
364 * @return the current autosave setting, i.e. true if setAutoSaveSettings() was called,
365 * false by default or if resetAutoSaveSettings() was called.
366 * @since 3.1
367 */
368 bool autoSaveSettings() const;
369
370 /**
371 * @return the group used for setting-autosaving.
372 * Only meaningful if setAutoSaveSettings() was called.
373 * This can be useful for forcing a save or an apply, e.g. before and after
374 * using KEditToolbar.
375 * @since 3.1
376 */
377 QString autoSaveGroup() const;
378
379 /**
380 * Read settings for statusbar, menubar and toolbar from their respective
381 * groups in the config file and apply them.
382 *
383 * @param config Config file to read the settings from.
384 * @param groupName Group name to use. If not specified, the last used
385 * group name is used.
386 */
387 void applyMainWindowSettings(KConfig *config, const QString &groupName = QString::null);
388
389 /**
390 * Save settings for statusbar, menubar and toolbar to their respective
391 * groups in the config file @p config.
392 *
393 * @param config Config file to save the settings to.
394 * @param groupName Group name to use. If not specified, the last used
395 * group name is used
396 */
397 void saveMainWindowSettings(KConfig *config, const QString &groupName = QString::null);
398
399 /**
400 * Sets whether KMainWindow should provide a menu that allows showing/hiding
401 * the available toolbars ( using @ref KToggleToolBarAction ) . In case there
402 * is only one toolbar configured a simple 'Show <toolbar name here>' menu item
403 * is shown.
404 *
405 * The menu / menu item is implemented using xmlgui. It will be inserted in your
406 * menu structure in the 'Settings' menu.
407 *
408 * If your application uses a non-standard xmlgui resource file then you can
409 * specify the exact position of the menu / menu item by adding a
410 * &lt;Merge name="StandardToolBarMenuHandler" /&gt;
411 * line to the settings menu section of your resource file ( usually appname.rc ).
412 *
413 * Note that you should enable this feature before calling createGUI() ( or similar ) .
414 * You enable/disable it anytime if you pass false to the conserveMemory argument of createGUI.
415 * @since 3.1
416 */
417 void setStandardToolBarMenuEnabled( bool enable );
418 /// @since 3.1
419 bool isStandardToolBarMenuEnabled() const;
420
421
422 /**
423 * Sets whether KMainWindow should provide a menu that allows showing/hiding
424 * of the statusbar ( using @ref KToggleStatusBarAction ).
425 *
426 * The menu / menu item is implemented using xmlgui. It will be inserted
427 * in your menu structure in the 'Settings' menu.
428 *
429 * Note that you should enable this feature before calling createGUI()
430 * ( or similar ).
431 *
432 * If an application maintains the action on its own (i.e. never calls
433 * this function) a connection needs to be made to let KMainWindow
434 * know when that status (hidden/shown) of the statusbar has changed.
435 * For example:
436 * connect(action, SIGNAL(activated()),
437 * kmainwindow, SLOT(setSettingsDirty()));
438 * Otherwise the status (hidden/show) of the statusbar might not be saved
439 * by KMainWindow.
440 * @since 3.2
441 */
442 void createStandardStatusBarAction();
443
444
445 /**
446 * Returns a pointer to the mainwindows action responsible for the toolbars menu
447 * @since 3.1
448 */
449 KAction *toolBarMenuAction();
450
451 // why do we support old gcc versions? using KXMLGUIBuilder::finalizeGUI;
452 /// @since 3.1
453 virtual void finalizeGUI( KXMLGUIClient *client );
454
455 /**
456 * @internal
457 */
458 void finalizeGUI( bool force );
459
460 /**
461 * @return true if a -geometry argument was given on the command line,
462 * and this is the first window created (the one on which this option applies)
463 */
464 bool initialGeometrySet() const;
465
466 /**
467 * @internal
468 * Used from Konqueror when reusing the main window.
469 */
470 void ignoreInitialGeometry();
471
472 /**
473 * @return the size the mainwindow should have so that the central
474 * widget will be of @p size.
475 */
476 QSize sizeForCentralWidgetSize(QSize size);
477
478public slots:
479 /**
480 * Makes a KDE compliant caption.
481 *
482 * @param caption Your caption. @em Do @em not include the application name
483 * in this string. It will be added automatically according to the KDE
484 * standard.
485 */
486 virtual void setCaption( const QString &caption );
487 /**
488 * Makes a KDE compliant caption.
489 *
490 * @param caption Your caption. @em Do @em not include the application name
491 * in this string. It will be added automatically according to the KDE
492 * standard.
493 * @param modified Specify whether the document is modified. This displays
494 * an additional sign in the title bar, usually "**".
495 */
496 virtual void setCaption( const QString &caption, bool modified );
497
498 /**
499 * Make a plain caption without any modifications.
500 *
501 * @param caption Your caption. This is the string that will be
502 * displayed in the window title.
503 */
504 virtual void setPlainCaption( const QString &caption );
505
506 /**
507 * Open the help page for the application.
508 *
509 * The application name is
510 * used as a key to determine what to display and the system will attempt
511 * to open <appName>/index.html.
512 *
513 * This method is intended for use by a help button in the toolbar or
514 * components outside the regular help menu. Use @ref helpMenu() when you
515 * want to provide access to the help system from the help menu.
516 *
517 * Example (adding a help button to the first toolbar):
518 *
519 * <pre>
520 * KIconLoader &loader = *KGlobal::iconLoader();
521 * QPixmap pixmap = loader.loadIcon( "help" );
522 * toolBar(0)->insertButton( pixmap, 0, SIGNAL(clicked()),
523 * this, SLOT(appHelpActivated()), true, i18n("Help") );
524 * </pre>
525 *
526 */
527//US void appHelpActivated( void );
528
529 /**
530 * Apply a state change
531 *
532 * Enable and disable actions as defined in the XML rc file
533 * @since 3.1
534 */
535 virtual void slotStateChanged(const QString &newstate);
536
537 /**
538 * Apply a state change
539 *
540 * Enable and disable actions as defined in the XML rc file,
541 * can "reverse" the state (disable the actions which should be
542 * enabled, and vice-versa) if specified.
543 * @since 3.1
544 */
545 void slotStateChanged(const QString &newstate,
546 KXMLGUIClient::ReverseStateChange); // KDE 4.0: remove this
547
548
549 /**
550 * Apply a state change
551 *
552 * Enable and disable actions as defined in the XML rc file,
553 * can "reverse" the state (disable the actions which should be
554 * enabled, and vice-versa) if specified.
555 */
556// void slotStateChanged(const QString &newstate,
557// bool reverse); // KDE 4.0: enable this
558
559 /**
560 * Tell the main window that it should save its settings when being closed.
561 * This is part of the auto-save-settings feature.
562 * For everything related to toolbars this happens automatically,
563 * but you have to call setSettingsDirty() in the slot that toggles
564 * the visibility of the statusbar.
565 */
566 void setSettingsDirty();
567
568protected:
569 void paintEvent( QPaintEvent* e );
570 void childEvent( QChildEvent* e);
571 void resizeEvent( QResizeEvent* e);
572 /**
573 * Reimplemented to call the queryClose() and queryExit() handlers.
574 *
575 * We recommend that you reimplement the handlers rather than @ref closeEvent().
576 * If you do it anyway, ensure to call the base implementation to keep
577 * @ref queryExit() running.
578 */
579 virtual void closeEvent ( QCloseEvent *);
580
581 // KDE4 This seems to be flawed to me. Either the app has only one
582 // mainwindow, so queryClose() is enough, or if it can have more of them,
583 // then the windows should take care of themselves, and queryExit()
584 // would be useful only for the annoying 'really quit' dialog, which
585 // also doesn't make sense in apps with multiple mainwindows.
586 // And saving configuration in something called queryExit()? IMHO
587 // one can e.g. use KApplication::shutDown(), which if nothing else
588 // has at least better fitting name.
589 // See also KApplication::sessionSaving().
590 // This stuff should get changed somehow, so that it at least doesn't
591 // mess with session management.
592 /**
593 Called before the very last window is closed, either by the
594 user or indirectly by the session manager.
595
596 It is not recommended to do any user interaction in this
597 function other than indicating severe errors. Better ask the
598 user on @ref queryClose() (see below).
599
600 A typical usage of @ref queryExit() is to write configuration data back.
601 Note that the application may continue to run after @ref queryExit()
602 (the user may have cancelled a shutdown), so you should not do any cleanups
603 here. The purpose of @ref queryExit() is purely to prepare the application
604 (with possible user interaction) so it can safely be closed later (without
605 user interaction).
606
607 If you need to do serious things on exit (like shutting a
608 dial-up connection down), connect to the signal
609 @ref KApplication::shutDown().
610
611 Default implementation returns @p true. Returning @p false will
612 cancel the exiting. In the latter case, the last window will
613 remain visible. If KApplication::sessionSaving() is true, refusing
614 the exit will also cancel KDE logout.
615
616 @see queryClose()
617 @see KApplication::sessionSaving()
618 */
619 virtual bool queryExit();
620
621 /**
622 Called before the window is closed, either by the user or indirectly by
623 the session manager.
624
625 The purpose of this function is to prepare the window in a way that it is
626 safe to close it, i.e. without the user losing some data.
627
628 Default implementation returns true. Returning @p false will cancel
629 the closing, and, if KApplication::sessionSaving() is true, it will also
630 cancel KDE logout.
631
632 Reimplement this function to prevent the user from losing data.
633 Example:
634 <pre>
635
636 switch ( KMessageBox::warningYesNoCancel( this,
637 i18n("Save changes to document foo?")) ) {
638 case KMessageBox::Yes :
639 // save document here. If saving fails, return FALSE;
640 return TRUE;
641 case KMessageBox::No :
642 return TRUE;
643 default: // cancel
644 return FALSE;
645
646 </pre>
647
648 @see queryExit()
649 @see KApplication::sessionSaving()
650
651 */
652 virtual bool queryClose();
653 /**
654 * Save your instance-specific properties. The function is
655 * invoked when the session manager requests your application
656 * to save its state.
657 *
658 * You @em must @em not change the group of the @p kconfig object, since
659 * KMainWindow uses one group for each window. Please
660 * reimplement these function in childclasses.
661 *
662 * Note: No user interaction is allowed
663 * in this function!
664 *
665 */
666 virtual void saveProperties( KConfig* ) {}
667
668 /**
669 * Read your instance-specific properties.
670 */
671 virtual void readProperties( KConfig* ) {}
672
673 /**
674 * Save your application-wide properties. The function is
675 * invoked when the session manager requests your application
676 * to save its state.
677 *
678 * This function is similar to @ref saveProperties() but is only called for
679 * the very first main window, regardless how many main window are open.
680
681 * Override it if you need to save other data about your documents on
682 * session end. sessionConfig is a config to which that data should be
683 * saved. Normally, you don't need this function. But if you want to save
684 * data about your documents that are not in opened windows you might need
685 * it.
686 *
687 * Default implementation does nothing.
688 */
689 virtual void saveGlobalProperties( KConfig* sessionConfig );
690
691 /**
692 * The counterpart of @ref saveGlobalProperties().
693 *
694 * Read the application-specific properties in again.
695 */
696 virtual void readGlobalProperties( KConfig* sessionConfig );
697 void savePropertiesInternal( KConfig*, int );
698 bool readPropertiesInternal( KConfig*, int );
699
700 /**
701 * For inherited classes
702 */
703 bool settingsDirty() const;
704 /**
705 * For inherited classes
706 */
707 QString settingsGroup() const;
708 /**
709 * For inherited classes
710 * Note that the group must be set before calling
711 */
712 void saveWindowSize( KConfig * config ) const;
713 /**
714 * For inherited classes
715 * Note that the group must be set before calling, and that
716 * a -geometry on the command line has priority.
717 */
718 void restoreWindowSize( KConfig * config );
719
720 /// parse the geometry from the geometry command line argument
721 void parseGeometry(bool parsewidth);
722
723protected slots:
724
725 /**
726 * This slot does nothing.
727 *
728 * It must be reimplemented if you want
729 * to use a custom About Application dialog box. This slot is
730 * connected to the About Application entry in the menu returned
731 * by @ref customHelpMenu.
732 *
733 * Example:
734 * <pre>
735 *
736 * void MyMainLevel::setupInterface()
737 * {
738 * ..
739 * menuBar()->insertItem( i18n("&Help"), customHelpMenu() );
740 * ..
741 * }
742 *
743 * void MyMainLevel::showAboutApplication()
744 * {
745 * <activate your custom dialog>
746 * }
747 * </pre>
748 */
749//US virtual void showAboutApplication();
750
751private slots:
752 /**
753 * Called when the app is shutting down.
754 */
755 void shuttingDown();
756
757 void saveAutoSaveSettings();
758
759private:
760 QToolBar * mQToolBar;
761//US KMenuBar *internalMenuBar();
762 QMenuBar *internalMenuBar();
763//US KStatusBar *internalStatusBar();
764 QStatusBar *internalStatusBar();
765
766 KMainWindowPrivate *d;
767 void initKMainWindow(const char *name);
768
769 QPtrList<KToolBar> toolbarList;
770
771protected:
772 virtual void virtual_hook( int id, void* data );
773
774};
775
776#endif
diff --git a/microkde/kdeui/knuminput.cpp b/microkde/kdeui/knuminput.cpp
new file mode 100644
index 0000000..335d6f4
--- a/dev/null
+++ b/microkde/kdeui/knuminput.cpp
@@ -0,0 +1,1095 @@
1// -*- c-basic-offset: 4 -*-
2/*
3 * knuminput.cpp
4 *
5 * Initial implementation:
6 * Copyright (c) 1997 Patrick Dowler <dowler@morgul.fsh.uvic.ca>
7 * Rewritten and maintained by:
8 * Copyright (c) 2000 Dirk A. Mueller <mueller@kde.org>
9 * KDoubleSpinBox:
10 * Copyright (c) 2002 Marc Mutz <mutz@kde.org>
11 *
12 * Requires the Qt widget libraries, available at no cost at
13 * http://www.troll.no/
14 *
15 * This library is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU Library General Public
17 * License as published by the Free Software Foundation; either
18 * version 2 of the License, or (at your option) any later version.
19 *
20 * This library is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 * Library General Public License for more details.
24 *
25 * You should have received a copy of the GNU Library General Public License
26 * along with this library; see the file COPYING.LIB. If not, write to
27 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
28 * Boston, MA 02111-1307, USA.
29 */
30
31//US #include <config.h>
32#ifdef HAVE_LIMITS_H
33#include <limits.h>
34#endif
35#include <assert.h>
36#include <math.h>
37#include <algorithm>
38
39#include <qlabel.h>
40#include <qlineedit.h>
41#include <qsize.h>
42#include <qslider.h>
43#include <qspinbox.h>
44#include <qstyle.h>
45
46#include <kglobal.h>
47#include <klocale.h>
48#include <kdebug.h>
49
50#include "knumvalidator.h"
51#include "knuminput.h"
52
53static inline int calcDiffByTen( int x, int y ) {
54 // calculate ( x - y ) / 10 without overflowing ints:
55 return ( x / 10 ) - ( y / 10 ) + ( x % 10 - y % 10 ) / 10;
56}
57
58// ----------------------------------------------------------------------------
59
60KNumInput::KNumInput(QWidget* parent, const char* name)
61 : QWidget(parent, name)
62{
63 init();
64}
65
66KNumInput::KNumInput(KNumInput* below, QWidget* parent, const char* name)
67 : QWidget(parent, name)
68{
69 init();
70
71 if(below) {
72 m_next = below->m_next;
73 m_prev = below;
74 below->m_next = this;
75 if(m_next)
76 m_next->m_prev = this;
77 }
78}
79
80void KNumInput::init()
81{
82 m_prev = m_next = 0;
83 m_colw1 = m_colw2 = 0;
84
85 m_label = 0;
86 m_slider = 0;
87 m_alignment = 0;
88}
89
90KNumInput::~KNumInput()
91{
92 if(m_prev)
93 m_prev->m_next = m_next;
94
95 if(m_next)
96 m_next->m_prev = m_prev;
97}
98
99void KNumInput::setLabel(const QString & label, int a)
100{
101 if(label.isEmpty()) {
102 delete m_label;
103 m_label = 0;
104 m_alignment = 0;
105 }
106 else {
107 if (m_label) m_label->setText(label);
108 else m_label = new QLabel(label, this, "KNumInput::QLabel");
109 m_label->setAlignment((a & (~(AlignTop|AlignBottom|AlignVCenter)))
110 | AlignVCenter);
111 // if no vertical alignment set, use Top alignment
112 if(!(a & (AlignTop|AlignBottom|AlignVCenter)))
113 a |= AlignTop;
114 m_alignment = a;
115 }
116
117 layout(true);
118}
119
120QString KNumInput::label() const
121{
122 if (m_label) return m_label->text();
123 return QString::null;
124}
125
126void KNumInput::layout(bool deep)
127{
128 int w1 = m_colw1;
129 int w2 = m_colw2;
130
131 // label sizeHint
132 m_sizeLabel = (m_label ? m_label->sizeHint() : QSize(0,0));
133
134 if(m_label && (m_alignment & AlignVCenter))
135 m_colw1 = m_sizeLabel.width() + 4;
136 else
137 m_colw1 = 0;
138
139 // slider sizeHint
140 m_sizeSlider = (m_slider ? m_slider->sizeHint() : QSize(0, 0));
141
142 doLayout();
143
144 if(!deep) {
145 m_colw1 = w1;
146 m_colw2 = w2;
147 return;
148 }
149
150 KNumInput* p = this;
151 while(p) {
152 p->doLayout();
153 w1 = QMAX(w1, p->m_colw1);
154 w2 = QMAX(w2, p->m_colw2);
155 p = p->m_prev;
156 }
157
158 p = m_next;
159 while(p) {
160 p->doLayout();
161 w1 = QMAX(w1, p->m_colw1);
162 w2 = QMAX(w2, p->m_colw2);
163 p = p->m_next;
164 }
165
166 p = this;
167 while(p) {
168 p->m_colw1 = w1;
169 p->m_colw2 = w2;
170 p = p->m_prev;
171 }
172
173 p = m_next;
174 while(p) {
175 p->m_colw1 = w1;
176 p->m_colw2 = w2;
177 p = p->m_next;
178 }
179
180// kdDebug() << "w1 " << w1 << " w2 " << w2 << endl;
181}
182
183QSizePolicy KNumInput::sizePolicy() const
184{
185 return QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Fixed );
186}
187
188QSize KNumInput::sizeHint() const
189{
190 return minimumSizeHint();
191}
192
193void KNumInput::setSteps(int minor, int major)
194{
195 if(m_slider)
196 m_slider->setSteps( minor, major );
197}
198
199
200// ----------------------------------------------------------------------------
201
202KIntSpinBox::KIntSpinBox(QWidget *parent, const char *name)
203 : QSpinBox(0, 99, 1, parent, name)
204{
205 editor()->setAlignment(AlignRight);
206 val_base = 10;
207 setValue(0);
208}
209
210KIntSpinBox::~KIntSpinBox()
211{
212}
213
214KIntSpinBox::KIntSpinBox(int lower, int upper, int step, int value, int base,
215 QWidget* parent, const char* name)
216 : QSpinBox(lower, upper, step, parent, name)
217{
218 editor()->setAlignment(AlignRight);
219 val_base = base;
220 setValue(value);
221}
222
223void KIntSpinBox::setBase(int base)
224{
225 val_base = base;
226}
227
228
229int KIntSpinBox::base() const
230{
231 return val_base;
232}
233
234QString KIntSpinBox::mapValueToText(int v)
235{
236 return QString::number(v, val_base);
237}
238
239int KIntSpinBox::mapTextToValue(bool* ok)
240{
241 return cleanText().toInt(ok, val_base);
242}
243
244void KIntSpinBox::setEditFocus(bool mark)
245{
246 editor()->setFocus();
247 if(mark)
248 editor()->selectAll();
249}
250
251
252// ----------------------------------------------------------------------------
253
254class KIntNumInput::KIntNumInputPrivate {
255public:
256 int referencePoint;
257 short blockRelative;
258 KIntNumInputPrivate( int r )
259 : referencePoint( r ),
260 blockRelative( 0 ) {}
261};
262
263
264KIntNumInput::KIntNumInput(KNumInput* below, int val, QWidget* parent,
265 int _base, const char* name)
266 : KNumInput(below, parent, name)
267{
268 init(val, _base);
269}
270
271KIntNumInput::KIntNumInput(QWidget *parent, const char *name)
272 : KNumInput(parent, name)
273{
274 init(0, 10);
275}
276
277KIntNumInput::KIntNumInput(int val, QWidget *parent, int _base, const char *name)
278 : KNumInput(parent, name)
279{
280 init(val, _base);
281
282}
283
284void KIntNumInput::init(int val, int _base)
285{
286 d = new KIntNumInputPrivate( val );
287 m_spin = new KIntSpinBox(INT_MIN, INT_MAX, 1, val, _base, this, "KIntNumInput::KIntSpinBox");
288 m_spin->setValidator(new KIntValidator(this, _base, "KNumInput::KIntValidtr"));
289 connect(m_spin, SIGNAL(valueChanged(int)), SLOT(spinValueChanged(int)));
290 connect(this, SIGNAL(valueChanged(int)),
291 SLOT(slotEmitRelativeValueChanged(int)));
292
293 setFocusProxy(m_spin);
294 layout(true);
295}
296
297void KIntNumInput::setReferencePoint( int ref ) {
298 // clip to valid range:
299 ref = kMin( maxValue(), kMax( minValue(), ref ) );
300 d->referencePoint = ref;
301}
302
303int KIntNumInput::referencePoint() const {
304 return d->referencePoint;
305}
306
307void KIntNumInput::spinValueChanged(int val)
308{
309 if(m_slider)
310 m_slider->setValue(val);
311
312 emit valueChanged(val);
313}
314
315void KIntNumInput::slotEmitRelativeValueChanged( int value ) {
316 if ( d->blockRelative || !d->referencePoint ) return;
317 emit relativeValueChanged( double( value ) / double( d->referencePoint ) );
318}
319
320void KIntNumInput::setRange(int lower, int upper, int step, bool slider)
321{
322 upper = kMax(upper, lower);
323 lower = kMin(upper, lower);
324 m_spin->setMinValue(lower);
325 m_spin->setMaxValue(upper);
326 m_spin->setLineStep(step);
327
328 step = m_spin->lineStep(); // maybe QRangeControl didn't like out lineStep?
329
330 if(slider) {
331 if (m_slider)
332 m_slider->setRange(lower, upper);
333 else {
334 m_slider = new QSlider(lower, upper, step, m_spin->value(),
335 QSlider::Horizontal, this);
336 m_slider->setTickmarks(QSlider::Below);
337 connect(m_slider, SIGNAL(valueChanged(int)),
338 m_spin, SLOT(setValue(int)));
339 }
340
341 // calculate (upper-lower)/10 without overflowing int's:
342 int major = calcDiffByTen( upper, lower );
343 if ( major==0 ) major = step; // #### workaround Qt bug in 2.1-beta4
344
345 m_slider->setSteps(step, major);
346 m_slider->setTickInterval(major);
347 }
348 else {
349 delete m_slider;
350 m_slider = 0;
351 }
352
353 // check that reference point is still inside valid range:
354 setReferencePoint( referencePoint() );
355
356 layout(true);
357}
358
359void KIntNumInput::setMinValue(int min)
360{
361 setRange(min, m_spin->maxValue(), m_spin->lineStep(), m_slider);
362}
363
364int KIntNumInput::minValue() const
365{
366 return m_spin->minValue();
367}
368
369void KIntNumInput::setMaxValue(int max)
370{
371 setRange(m_spin->minValue(), max, m_spin->lineStep(), m_slider);
372}
373
374int KIntNumInput::maxValue() const
375{
376 return m_spin->maxValue();
377}
378
379void KIntNumInput::setSuffix(const QString &suffix)
380{
381 m_spin->setSuffix(suffix);
382
383 layout(true);
384}
385
386QString KIntNumInput::suffix() const
387{
388 return m_spin->suffix();
389}
390
391void KIntNumInput::setPrefix(const QString &prefix)
392{
393 m_spin->setPrefix(prefix);
394
395 layout(true);
396}
397
398QString KIntNumInput::prefix() const
399{
400 return m_spin->prefix();
401}
402
403void KIntNumInput::setEditFocus(bool mark)
404{
405 m_spin->setEditFocus(mark);
406}
407
408QSize KIntNumInput::minimumSizeHint() const
409{
410 constPolish();
411
412 int w;
413 int h;
414
415 h = 2 + QMAX(m_sizeSpin.height(), m_sizeSlider.height());
416
417 // if in extra row, then count it here
418 if(m_label && (m_alignment & (AlignBottom|AlignTop)))
419 h += 4 + m_sizeLabel.height();
420 else
421 // label is in the same row as the other widgets
422 h = QMAX(h, m_sizeLabel.height() + 2);
423
424 w = m_slider ? m_slider->sizeHint().width() + 8 : 0;
425 w += m_colw1 + m_colw2;
426
427 if(m_alignment & (AlignTop|AlignBottom))
428 w = QMAX(w, m_sizeLabel.width() + 4);
429
430 return QSize(w, h);
431}
432
433void KIntNumInput::doLayout()
434{
435 m_sizeSpin = m_spin->sizeHint();
436 m_colw2 = m_sizeSpin.width();
437
438 if (m_label)
439 m_label->setBuddy(m_spin);
440}
441
442void KIntNumInput::resizeEvent(QResizeEvent* e)
443{
444 int w = m_colw1;
445 int h = 0;
446
447 if(m_label && (m_alignment & AlignTop)) {
448 m_label->setGeometry(0, 0, e->size().width(), m_sizeLabel.height());
449 h += m_sizeLabel.height() + 4;
450 }
451
452 if(m_label && (m_alignment & AlignVCenter))
453 m_label->setGeometry(0, 0, w, m_sizeSpin.height());
454
455 m_spin->setGeometry(w, h, m_slider ? m_colw2 : QMAX(m_colw2, e->size().width() - w), m_sizeSpin.height());
456 w += m_colw2 + 8;
457
458 if(m_slider)
459 m_slider->setGeometry(w, h, e->size().width() - w, m_sizeSpin.height());
460
461 h += m_sizeSpin.height() + 2;
462
463 if(m_label && (m_alignment & AlignBottom))
464 m_label->setGeometry(0, h, m_sizeLabel.width(), m_sizeLabel.height());
465}
466
467KIntNumInput::~KIntNumInput()
468{
469 delete d;
470}
471
472void KIntNumInput::setValue(int val)
473{
474 m_spin->setValue(val);
475 // slider value is changed by spinValueChanged
476}
477
478void KIntNumInput::setRelativeValue( double r ) {
479 if ( !d->referencePoint ) return;
480 ++d->blockRelative;
481 setValue( int( d->referencePoint * r + 0.5 ) );
482 --d->blockRelative;
483}
484
485double KIntNumInput::relativeValue() const {
486 if ( !d->referencePoint ) return 0;
487 return double( value() ) / double ( d->referencePoint );
488}
489
490int KIntNumInput::value() const
491{
492 return m_spin->value();
493}
494
495void KIntNumInput::setSpecialValueText(const QString& text)
496{
497 m_spin->setSpecialValueText(text);
498 layout(true);
499}
500
501QString KIntNumInput::specialValueText() const
502{
503 return m_spin->specialValueText();
504}
505
506void KIntNumInput::setLabel(const QString & label, int a)
507{
508 KNumInput::setLabel(label, a);
509
510 if(m_label)
511 m_label->setBuddy(m_spin);
512}
513
514// ----------------------------------------------------------------------------
515
516class KDoubleNumInput::KDoubleNumInputPrivate {
517public:
518 KDoubleNumInputPrivate( double r )
519 : spin( 0 ),
520 referencePoint( r ),
521 blockRelative ( 0 ) {}
522 KDoubleSpinBox * spin;
523 double referencePoint;
524 short blockRelative;
525};
526
527KDoubleNumInput::KDoubleNumInput(QWidget *parent, const char *name)
528 : KNumInput(parent, name)
529{
530 init(0.0, 0.0, 9999.0, 0.01, 2);
531}
532
533KDoubleNumInput::KDoubleNumInput(double lower, double upper, double value,
534 double step, int precision, QWidget* parent,
535 const char *name)
536 : KNumInput(parent, name)
537{
538 init(value, lower, upper, step, precision);
539}
540
541KDoubleNumInput::KDoubleNumInput(KNumInput *below,
542 double lower, double upper, double value,
543 double step, int precision, QWidget* parent,
544 const char *name)
545 : KNumInput(below, parent, name)
546{
547 init(value, lower, upper, step, precision);
548}
549
550KDoubleNumInput::KDoubleNumInput(double value, QWidget *parent, const char *name)
551 : KNumInput(parent, name)
552{
553 init(value, kMin(0.0, value), kMax(0.0, value), 0.01, 2 );
554}
555
556KDoubleNumInput::KDoubleNumInput(KNumInput* below, double value, QWidget* parent,
557 const char* name)
558 : KNumInput(below, parent, name)
559{
560 init( value, kMin(0.0, value), kMax(0.0, value), 0.01, 2 );
561}
562
563KDoubleNumInput::~KDoubleNumInput()
564{
565 delete d;
566}
567
568// ### remove when BIC changes are allowed again:
569
570bool KDoubleNumInput::eventFilter( QObject * o, QEvent * e ) {
571 return KNumInput::eventFilter( o, e );
572}
573
574void KDoubleNumInput::resetEditBox() {
575
576}
577
578// ### end stuff to remove when BIC changes are allowed again
579
580
581
582void KDoubleNumInput::init(double value, double lower, double upper,
583 double step, int precision )
584{
585 // ### init no longer used members:
586 edit = 0;
587 m_range = true;
588 m_value = 0.0;
589 m_precision = 2;
590 // ### end
591
592 d = new KDoubleNumInputPrivate( value );
593
594 d->spin = new KDoubleSpinBox( lower, upper, step, value, precision,
595 this, "KDoubleNumInput::d->spin" );
596 setFocusProxy(d->spin);
597 connect( d->spin, SIGNAL(valueChanged(double)),
598 this, SIGNAL(valueChanged(double)) );
599 connect( this, SIGNAL(valueChanged(double)),
600 this, SLOT(slotEmitRelativeValueChanged(double)) );
601
602 updateLegacyMembers();
603
604 layout(true);
605}
606
607void KDoubleNumInput::updateLegacyMembers() {
608 // ### update legacy members that are either not private or for
609 // which an inlined getter exists:
610 m_lower = minValue();
611 m_upper = maxValue();
612 m_step = d->spin->lineStep();
613 m_specialvalue = specialValueText();
614}
615
616
617double KDoubleNumInput::mapSliderToSpin( int val ) const
618{
619 // map [slidemin,slidemax] to [spinmin,spinmax]
620 double spinmin = d->spin->minValue();
621 double spinmax = d->spin->maxValue();
622 double slidemin = m_slider->minValue(); // cast int to double to avoid
623 double slidemax = m_slider->maxValue(); // overflow in rel denominator
624 double rel = ( double(val) - slidemin ) / ( slidemax - slidemin );
625 return spinmin + rel * ( spinmax - spinmin );
626}
627
628void KDoubleNumInput::sliderMoved(int val)
629{
630 d->spin->setValue( mapSliderToSpin( val ) );
631}
632
633void KDoubleNumInput::slotEmitRelativeValueChanged( double value )
634{
635 if ( !d->referencePoint ) return;
636 emit relativeValueChanged( value / d->referencePoint );
637}
638
639QSize KDoubleNumInput::minimumSizeHint() const
640{
641 constPolish();
642
643 int w;
644 int h;
645
646 h = 2 + QMAX(m_sizeEdit.height(), m_sizeSlider.height());
647
648 // if in extra row, then count it here
649 if(m_label && (m_alignment & (AlignBottom|AlignTop)))
650 h += 4 + m_sizeLabel.height();
651 else
652 // label is in the same row as the other widgets
653 h = QMAX(h, m_sizeLabel.height() + 2);
654
655 w = m_slider ? m_slider->sizeHint().width() + 8 : 0;
656 w += m_colw1 + m_colw2;
657
658 if(m_alignment & (AlignTop|AlignBottom))
659 w = QMAX(w, m_sizeLabel.width() + 4);
660
661 return QSize(w, h);
662}
663
664void KDoubleNumInput::resizeEvent(QResizeEvent* e)
665{
666 int w = m_colw1;
667 int h = 0;
668
669 if(m_label && (m_alignment & AlignTop)) {
670 m_label->setGeometry(0, 0, e->size().width(), m_sizeLabel.height());
671 h += m_sizeLabel.height() + 4;
672 }
673
674 if(m_label && (m_alignment & AlignVCenter))
675 m_label->setGeometry(0, 0, w, m_sizeEdit.height());
676
677 d->spin->setGeometry(w, h, m_slider ? m_colw2
678 : e->size().width() - w, m_sizeEdit.height());
679 w += m_colw2 + 8;
680
681 if(m_slider)
682 m_slider->setGeometry(w, h, e->size().width() - w, m_sizeEdit.height());
683
684 h += m_sizeEdit.height() + 2;
685
686 if(m_label && (m_alignment & AlignBottom))
687 m_label->setGeometry(0, h, m_sizeLabel.width(), m_sizeLabel.height());
688}
689
690void KDoubleNumInput::doLayout()
691{
692 m_sizeEdit = d->spin->sizeHint();
693 m_colw2 = m_sizeEdit.width();
694}
695
696void KDoubleNumInput::setValue(double val)
697{
698 d->spin->setValue( val );
699}
700
701void KDoubleNumInput::setRelativeValue( double r )
702{
703 if ( !d->referencePoint ) return;
704 ++d->blockRelative;
705 setValue( r * d->referencePoint );
706 --d->blockRelative;
707}
708
709void KDoubleNumInput::setReferencePoint( double ref )
710{
711 // clip to valid range:
712 ref = kMin( maxValue(), kMax( minValue(), ref ) );
713 d->referencePoint = ref;
714}
715
716void KDoubleNumInput::setRange(double lower, double upper, double step,
717 bool slider)
718{
719 if( m_slider ) {
720 // don't update the slider to avoid an endless recursion
721 QSpinBox * spin = d->spin;
722 disconnect(spin, SIGNAL(valueChanged(int)),
723 m_slider, SLOT(setValue(int)) );
724 }
725 d->spin->setRange( lower, upper, step, d->spin->precision() );
726
727 if(slider) {
728 // upcast to base type to get the min/maxValue in int form:
729 QSpinBox * spin = d->spin;
730 int slmax = spin->maxValue();
731 int slmin = spin->minValue();
732 int slvalue = spin->value();
733 int slstep = spin->lineStep();
734 if (m_slider) {
735 m_slider->setRange(slmin, slmax);
736 m_slider->setLineStep(slstep);
737 m_slider->setValue(slvalue);
738 } else {
739 m_slider = new QSlider(slmin, slmax, slstep, slvalue,
740 QSlider::Horizontal, this);
741 m_slider->setTickmarks(QSlider::Below);
742 // feedback line: when one moves, the other moves, too:
743 connect(m_slider, SIGNAL(valueChanged(int)),
744 SLOT(sliderMoved(int)) );
745 }
746 connect(spin, SIGNAL(valueChanged(int)),
747 m_slider, SLOT(setValue(int)) );
748 // calculate ( slmax - slmin ) / 10 without overflowing ints:
749 int major = calcDiffByTen( slmax, slmin );
750 if ( !major ) major = slstep; // ### needed?
751 m_slider->setTickInterval(major);
752 } else {
753 delete m_slider;
754 m_slider = 0;
755 }
756
757 setReferencePoint( referencePoint() );
758
759 layout(true);
760 updateLegacyMembers();
761}
762
763void KDoubleNumInput::setMinValue(double min)
764{
765 setRange(min, maxValue(), d->spin->lineStep(), m_slider);
766}
767
768double KDoubleNumInput::minValue() const
769{
770 return d->spin->minValue();
771}
772
773void KDoubleNumInput::setMaxValue(double max)
774{
775 setRange(minValue(), max, d->spin->lineStep(), m_slider);
776}
777
778double KDoubleNumInput::maxValue() const
779{
780 return d->spin->maxValue();
781}
782
783double KDoubleNumInput::value() const
784{
785 return d->spin->value();
786}
787
788double KDoubleNumInput::relativeValue() const
789{
790 if ( !d->referencePoint ) return 0;
791 return value() / d->referencePoint;
792}
793
794double KDoubleNumInput::referencePoint() const
795{
796 return d->referencePoint;
797}
798
799QString KDoubleNumInput::suffix() const
800{
801 return d->spin->suffix();
802}
803
804QString KDoubleNumInput::prefix() const
805{
806 return d->spin->prefix();
807}
808
809void KDoubleNumInput::setSuffix(const QString &suffix)
810{
811 d->spin->setSuffix( suffix );
812
813 layout(true);
814}
815
816void KDoubleNumInput::setPrefix(const QString &prefix)
817{
818 d->spin->setPrefix( prefix );
819
820 layout(true);
821}
822
823void KDoubleNumInput::setPrecision(int precision)
824{
825 d->spin->setPrecision( precision );
826
827 layout(true);
828}
829
830int KDoubleNumInput::precision() const
831{
832 return d->spin->precision();
833}
834
835void KDoubleNumInput::setSpecialValueText(const QString& text)
836{
837 d->spin->setSpecialValueText( text );
838
839 layout(true);
840 updateLegacyMembers();
841}
842
843void KDoubleNumInput::setLabel(const QString & label, int a)
844{
845 KNumInput::setLabel(label, a);
846
847 if(m_label)
848 m_label->setBuddy(d->spin);
849
850}
851
852// ----------------------------------------------------------------------------
853
854
855// We use a kind of fixed-point arithmetic to represent the range of
856// doubles [mLower,mUpper] in steps of 10^(-mPrecision). Thus, the
857// following relations hold:
858//
859// 1. factor = 10^mPrecision
860// 2. basicStep = 1/factor = 10^(-mPrecision);
861// 3. lowerInt = lower * factor;
862// 4. upperInt = upper * factor;
863// 5. lower = lowerInt * basicStep;
864// 6. upper = upperInt * basicStep;
865class KDoubleSpinBox::Private {
866public:
867 Private( int precision=1 )
868 : mPrecision( precision ),
869 mValidator( 0 )
870 {
871 }
872
873 int factor() const {
874 int f = 1;
875 for ( int i = 0 ; i < mPrecision ; ++i ) f *= 10;
876 return f;
877 }
878
879 double basicStep() const {
880 return 1.0/double(factor());
881 }
882
883 int mapToInt( double value, bool * ok ) const {
884 assert( ok );
885 const double f = factor();
886 if ( value > double(INT_MAX) / f ) {
887 kdWarning() << "KDoubleSpinBox: can't represent value " << value
888 << "in terms of fixed-point numbers with precision "
889 << mPrecision << endl;
890 *ok = false;
891 return INT_MAX;
892 } else if ( value < double(INT_MIN) / f ) {
893 kdWarning() << "KDoubleSpinBox: can't represent value " << value
894 << "in terms of fixed-point numbers with precision "
895 << mPrecision << endl;
896 *ok = false;
897 return INT_MIN;
898 } else {
899 *ok = true;
900 return int( value * f + ( value < 0 ? -0.5 : 0.5 ) );
901 }
902 }
903
904 double mapToDouble( int value ) const {
905 return double(value) * basicStep();
906 }
907
908 int mPrecision;
909 KDoubleValidator * mValidator;
910};
911
912KDoubleSpinBox::KDoubleSpinBox( QWidget * parent, const char * name )
913 : QSpinBox( parent, name )
914{
915 editor()->setAlignment( Qt::AlignRight );
916 d = new Private();
917 updateValidator();
918}
919
920KDoubleSpinBox::KDoubleSpinBox( double lower, double upper, double step,
921 double value, int precision,
922 QWidget * parent, const char * name )
923 : QSpinBox( parent, name )
924{
925 editor()->setAlignment( Qt::AlignRight );
926 d = new Private();
927 setRange( lower, upper, step, precision );
928 setValue( value );
929 connect( this, SIGNAL(valueChanged(int)), SLOT(slotValueChanged(int)) );
930}
931
932KDoubleSpinBox::~KDoubleSpinBox() {
933 delete d; d = 0;
934}
935
936bool KDoubleSpinBox::acceptLocalizedNumbers() const {
937 if ( !d->mValidator ) return true; // we'll set one that does;
938 // can't do it now, since we're const
939 return d->mValidator->acceptLocalizedNumbers();
940}
941
942void KDoubleSpinBox::setAcceptLocalizedNumbers( bool accept ) {
943 if ( !d->mValidator ) updateValidator();
944 d->mValidator->setAcceptLocalizedNumbers( accept );
945}
946
947void KDoubleSpinBox::setRange( double lower, double upper, double step,
948 int precision ) {
949 lower = kMin(upper, lower);
950 upper = kMax(upper, lower);
951 setPrecision( precision, true ); // disable bounds checking, since
952 setMinValue( lower ); // it's done in set{Min,Max}Value
953 setMaxValue( upper ); // anyway and we want lower, upper
954 setLineStep( step ); // and step to have the right precision
955}
956
957int KDoubleSpinBox::precision() const {
958 return d->mPrecision;
959}
960
961void KDoubleSpinBox::setPrecision( int precision ) {
962 setPrecision( precision, false );
963}
964
965void KDoubleSpinBox::setPrecision( int precision, bool force ) {
966 if ( precision < 1 ) return;
967 if ( !force ) {
968 int maxPrec = maxPrecision();
969 if ( precision > maxPrec )
970 precision = maxPrec;
971 }
972 d->mPrecision = precision;
973 updateValidator();
974}
975
976int KDoubleSpinBox::maxPrecision() const {
977 // INT_MAX must be > maxAbsValue * 10^precision
978 // ==> 10^precision < INT_MAX / maxAbsValue
979 // ==> precision < log10 ( INT_MAX / maxAbsValue )
980 // ==> maxPrecision = floor( log10 ( INT_MAX / maxAbsValue ) );
981 double maxAbsValue = kMax( fabs(minValue()), fabs(maxValue()) );
982 if ( maxAbsValue == 0 ) return 6; // return arbitrary value to avoid dbz...
983
984 return int( floor( log10( double(INT_MAX) / maxAbsValue ) ) );
985}
986
987double KDoubleSpinBox::value() const {
988 return d->mapToDouble( base::value() );
989}
990
991void KDoubleSpinBox::setValue( double value ) {
992 if ( value == this->value() ) return;
993 if ( value < minValue() )
994 base::setValue( base::minValue() );
995 else if ( value > maxValue() )
996 base::setValue( base::maxValue() );
997 else {
998 bool ok = false;
999 base::setValue( d->mapToInt( value, &ok ) );
1000 assert( ok );
1001 }
1002}
1003
1004double KDoubleSpinBox::minValue() const {
1005 return d->mapToDouble( base::minValue() );
1006}
1007
1008void KDoubleSpinBox::setMinValue( double value ) {
1009 bool ok = false;
1010 int min = d->mapToInt( value, &ok );
1011 if ( !ok ) return;
1012 base::setMinValue( min );
1013 updateValidator();
1014}
1015
1016
1017double KDoubleSpinBox::maxValue() const {
1018 return d->mapToDouble( base::maxValue() );
1019}
1020
1021void KDoubleSpinBox::setMaxValue( double value ) {
1022 bool ok = false;
1023 int max = d->mapToInt( value, &ok );
1024 if ( !ok ) return;
1025 base::setMaxValue( max );
1026 updateValidator();
1027}
1028
1029double KDoubleSpinBox::lineStep() const {
1030 return d->mapToDouble( base::lineStep() );
1031}
1032
1033void KDoubleSpinBox::setLineStep( double step ) {
1034 bool ok = false;
1035 if ( step > maxValue() - minValue() )
1036 base::setLineStep( 1 );
1037 else
1038 base::setLineStep( kMax( d->mapToInt( step, &ok ), 1 ) );
1039}
1040
1041QString KDoubleSpinBox::mapValueToText( int value ) {
1042 if ( acceptLocalizedNumbers() )
1043 return KGlobal::locale()
1044 ->formatNumber( d->mapToDouble( value ), d->mPrecision );
1045 else
1046 return QString().setNum( d->mapToDouble( value ), 'f', d->mPrecision );
1047}
1048
1049int KDoubleSpinBox::mapTextToValue( bool * ok ) {
1050 double value;
1051 if ( acceptLocalizedNumbers() )
1052 value = KGlobal::locale()->readNumber( cleanText(), ok );
1053 else
1054 value = cleanText().toDouble( ok );
1055 if ( !*ok ) return 0;
1056 if ( value > maxValue() )
1057 value = maxValue();
1058 else if ( value < minValue() )
1059 value = minValue();
1060 return d->mapToInt( value, ok );
1061}
1062
1063void KDoubleSpinBox::setValidator( const QValidator * ) {
1064 // silently discard the new validator. We don't want another one ;-)
1065}
1066
1067void KDoubleSpinBox::slotValueChanged( int value ) {
1068 emit valueChanged( d->mapToDouble( value ) );
1069}
1070
1071void KDoubleSpinBox::updateValidator() {
1072 if ( !d->mValidator ) {
1073 d->mValidator = new KDoubleValidator( minValue(), maxValue(), precision(),
1074 this, "d->mValidator" );
1075 base::setValidator( d->mValidator );
1076 } else
1077 d->mValidator->setRange( minValue(), maxValue(), precision() );
1078}
1079
1080void KNumInput::virtual_hook( int, void* )
1081{ /*BASE::virtual_hook( id, data );*/ }
1082
1083void KIntNumInput::virtual_hook( int id, void* data )
1084{ KNumInput::virtual_hook( id, data ); }
1085
1086void KDoubleNumInput::virtual_hook( int id, void* data )
1087{ KNumInput::virtual_hook( id, data ); }
1088
1089void KIntSpinBox::virtual_hook( int, void* )
1090{ /*BASE::virtual_hook( id, data );*/ }
1091
1092void KDoubleSpinBox::virtual_hook( int, void* )
1093{ /*BASE::virtual_hook( id, data );*/ }
1094
1095//US #include "knuminput.moc"
diff --git a/microkde/kdeui/knuminput.h b/microkde/kdeui/knuminput.h
new file mode 100644
index 0000000..123fefa
--- a/dev/null
+++ b/microkde/kdeui/knuminput.h
@@ -0,0 +1,948 @@
1/*
2 * knuminput.h
3 *
4 * Copyright (c) 1997 Patrick Dowler <dowler@morgul.fsh.uvic.ca>
5 * Copyright (c) 2000 Dirk A. Mueller <mueller@kde.org>
6 * Copyright (c) 2002 Marc Mutz <mutz@kde.org>
7 *
8 * Requires the Qt widget libraries, available at no cost at
9 * http://www.troll.no/
10 *
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Library General Public
13 * License as published by the Free Software Foundation; either
14 * version 2 of the License, or (at your option) any later version.
15 *
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Library General Public License for more details.
20 *
21 * You should have received a copy of the GNU Library General Public License
22 * along with this library; see the file COPYING.LIB. If not, write to
23 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
24 * Boston, MA 02111-1307, USA.
25 */
26
27#ifndef K_NUMINPUT_H
28#define K_NUMINPUT_H
29
30#include <qwidget.h>
31#include <qspinbox.h>
32
33class QLabel;
34class QSlider;
35class QLineEdit;
36class QLayout;
37class QValidator;
38
39class KIntSpinBox;
40
41/* ------------------------------------------------------------------------ */
42
43/**
44 * You need to inherit from this class if you want to implement K*NumInput
45 * for a different variable type
46 *
47 */
48class KNumInput : public QWidget
49{
50 Q_OBJECT
51 Q_PROPERTY( QString label READ label WRITE setLabel )
52public:
53 /**
54 * Default constructor
55 *
56 */
57 KNumInput(QWidget* parent=0, const char* name=0);
58
59 /**
60 * @param below A pointer to another KNumInput.
61 *
62 */
63 KNumInput(KNumInput* below, QWidget* parent=0, const char* name=0);
64 ~KNumInput();
65
66 /**
67 * Sets the text and alignment of the main description label.
68 *
69 * @param label The text of the label.
70 * Use QString::null to remove an existing one.
71 *
72 * @param a one of @p AlignLeft, @p AlignHCenter, YAlignRight and
73 * @p AlignTop, @p AlignVCenter, @p AlignBottom.
74 * default is @p AlignLeft | @p AlignTop.
75 *
76 * The vertical alignment flags have special meaning with this
77 * widget:
78 *
79 * @li @p AlignTop The label is placed above the edit/slider
80 * @li @p AlignVCenter The label is placed left beside the edit
81 * @li @p AlignBottom The label is placed below the edit/slider
82 *
83 */
84 virtual void setLabel(const QString & label, int a = AlignLeft | AlignTop);
85
86 /**
87 * @return the text of the label.
88 */
89 QString label() const;
90
91 /**
92 * @return if the num input has a slider.
93 * @since 3.1
94 */
95 bool showSlider() const { return m_slider; }
96
97 /**
98 * Sets the spacing of tickmarks for the slider.
99 *
100 * @param minor Minor tickmark separation.
101 * @param major Major tickmark separation.
102 */
103 void setSteps(int minor, int major);
104
105 /**
106 * Specifies that this widget may stretch horizontally, but is
107 * fixed vertically (like @ref QSpinBox itself).
108 */
109 QSizePolicy sizePolicy() const;
110
111 /**
112 * Returns a size which fits the contents of the control.
113 *
114 * @return the preferred size necessary to show the control
115 */
116 virtual QSize sizeHint() const;
117
118protected:
119 /**
120 * Call this function whenever you change something in the geometry
121 * of your KNumInput child.
122 *
123 */
124 void layout(bool deep);
125
126 /**
127 * You need to overwrite this method and implement your layout
128 * calculations there.
129 *
130 * See KIntNumInput::doLayout and KDoubleNumInput::doLayout implementation
131 * for details.
132 *
133 */
134 virtual void doLayout() = 0;
135
136 KNumInput* m_prev, *m_next;
137 int m_colw1, m_colw2;
138
139 QLabel* m_label;
140 QSlider* m_slider;
141 QSize m_sizeSlider, m_sizeLabel;
142
143 int m_alignment;
144
145private:
146 void init();
147
148protected:
149 virtual void virtual_hook( int id, void* data );
150private:
151 class KNumInputPrivate;
152 KNumInputPrivate *d;
153};
154
155/* ------------------------------------------------------------------------ */
156
157/**
158 * KIntNumInput combines a @ref QSpinBox and optionally a @ref QSlider
159 * with a label to make an easy to use control for setting some integer
160 * parameter. This is especially nice for configuration dialogs,
161 * which can have many such combinated controls.
162 *
163 * The slider is created only when the user specifies a range
164 * for the control using the setRange function with the slider
165 * parameter set to "true".
166 *
167 * A special feature of KIntNumInput, designed specifically for
168 * the situation when there are several KIntNumInputs in a column,
169 * is that you can specify what portion of the control is taken by the
170 * QSpinBox (the remaining portion is used by the slider). This makes
171 * it very simple to have all the sliders in a column be the same size.
172 *
173 * It uses @ref KIntValidator validator class. KIntNumInput enforces the
174 * value to be in the given range, and can display it in any base
175 * between 2 and 36.
176 *
177 * @short An input widget for integer numbers, consisting of a spinbox and a slider.
178 * @version $Id$
179 */
180
181class KIntNumInput : public KNumInput
182{
183 Q_OBJECT
184 Q_PROPERTY( int value READ value WRITE setValue )
185 Q_PROPERTY( int minValue READ minValue WRITE setMinValue )
186 Q_PROPERTY( int maxValue READ maxValue WRITE setMaxValue )
187 Q_PROPERTY( int referencePoint READ referencePoint WRITE setReferencePoint )
188 Q_PROPERTY( QString suffix READ suffix WRITE setSuffix )
189 Q_PROPERTY( QString prefix READ prefix WRITE setPrefix )
190 Q_PROPERTY( QString specialValueText READ specialValueText WRITE setSpecialValueText )
191
192public:
193 /**
194 * Constructs an input control for integer values
195 * with base 10 and initial value 0.
196 */
197 KIntNumInput(QWidget *parent=0, const char *name=0);
198 /**
199 * Constructor
200 * It constructs a QSpinBox that allows the input of integer numbers
201 * in the range of -INT_MAX to +INT_MAX. To set a descriptive label,
202 * use setLabel(). To enforce the value being in a range and optionally to
203 * attach a slider to it, use setRange().
204 *
205 * @param value initial value for the control
206 * @param base numeric base used for display
207 * @param parent parent QWidget
208 * @param name internal name for this widget
209 */
210 KIntNumInput(int value, QWidget* parent=0, int base = 10, const char *name=0);
211
212 /**
213 * Constructor
214 *
215 * the difference to the one above is the "below" parameter. It tells
216 * this instance that it is visually put below some other KNumInput widget.
217 * Note that these two KNumInput's need not to have the same parent widget
218 * or be in the same layout group.
219 * The effect is that it'll adjust it's layout in correspondence
220 * with the layout of the other KNumInput's (you can build an arbitary long
221 * chain).
222 *
223 * @param below append KIntNumInput to the KNumInput chain
224 * @param value initial value for the control
225 * @param base numeric base used for display
226 * @param parent parent QWidget
227 * @param name internal name for this widget
228 */
229 KIntNumInput(KNumInput* below, int value, QWidget* parent=0, int base = 10, const char *name=0);
230
231 /**
232 * Destructor
233 *
234 *
235 */
236 virtual ~KIntNumInput();
237
238 /**
239 * @return the current value.
240 */
241 int value() const;
242
243 /**
244 * @return the curent value in units of the @ref referencePoint.
245 * @since 3.1
246 */
247 double relativeValue() const;
248
249 /**
250 * @return the current reference point
251 * @since 3.1
252 */
253 int referencePoint() const;
254
255 /**
256 * @return the suffix displayed behind the value.
257 * @see #setSuffix()
258 */
259 QString suffix() const;
260 /**
261 * @return the prefix displayed in front of the value.
262 * @see #setPrefix()
263 */
264 QString prefix() const;
265 /**
266 * @return the string displayed for a special value.
267 * @see #setSpecialValueText()
268 */
269 QString specialValueText() const;
270
271 /**
272 * @param min minimum value
273 * @param max maximum value
274 * @param step step size for the QSlider
275 */
276 void setRange(int min, int max, int step=1, bool slider=true);
277 /**
278 * Sets the minimum value.
279 */
280 void setMinValue(int min);
281 /**
282 * @return the minimum value.
283 */
284 int minValue() const;
285 /**
286 * Sets the maximum value.
287 */
288 void setMaxValue(int max);
289 /**
290 * @return the maximum value.
291 */
292 int maxValue() const;
293
294 /**
295 * Sets the special value text. If set, the SpinBox will display
296 * this text instead of the numeric value whenever the current
297 * value is equal to minVal(). Typically this is used for indicating
298 * that the choice has a special (default) meaning.
299 */
300 void setSpecialValueText(const QString& text);
301
302 /**
303 * @reimplemented
304 */
305 virtual void setLabel(const QString & label, int a = AlignLeft | AlignTop);
306
307 /**
308 * This method returns the minimum size necessary to display the
309 * control. The minimum size is enough to show all the labels
310 * in the current font (font change may invalidate the return value).
311 *
312 * @return the minimum size necessary to show the control
313 */
314 virtual QSize minimumSizeHint() const;
315
316public slots:
317 /**
318 * Sets the value of the control.
319 */
320 void setValue(int);
321
322 /**
323 * Sets the value in units of the @ref referencePoint
324 * @since 3.1
325 */
326 void setRelativeValue(double);
327
328 /**
329 * Sets the reference point for @ref relativeValue.
330 * @since 3.1
331 */
332 void setReferencePoint(int);
333
334 /**
335 * Sets the suffix to @p suffix.
336 * Use QString::null to disable this feature.
337 * Formatting has to be provided (e.g. a space separator between the
338 * prepended @p value and the suffix's text has to be provided
339 * as the first character in the suffix).
340 *
341 * @see QSpinBox::setSuffix(), #setPrefix()
342 */
343 void setSuffix(const QString &suffix);
344
345 /**
346 * Sets the prefix to @p prefix.
347 * Use QString::null to disable this feature.
348 * Formatting has to be provided (see above).
349 *
350 * @see QSpinBox::setPrefix(), #setSuffix()
351 */
352 void setPrefix(const QString &prefix);
353
354 /**
355 * sets focus to the edit widget and marks all text in if mark == true
356 *
357 */
358 void setEditFocus( bool mark = true );
359
360signals:
361 /**
362 * Emitted every time the value changes (by calling @ref setValue() or
363 * by user interaction).
364 */
365 void valueChanged(int);
366
367 /**
368 * Emitted whenever @ref #valueChanged is. Contains the change
369 * relative to the @ref referencePoint.
370 * @since 3.1
371 */
372 void relativeValueChanged(double);
373
374private slots:
375 void spinValueChanged(int);
376 void slotEmitRelativeValueChanged(int);
377
378protected:
379 /**
380 * @reimplemented
381 */
382 virtual void doLayout();
383 /**
384 * @reimplemented
385 */
386 void resizeEvent ( QResizeEvent * );
387
388 KIntSpinBox* m_spin;
389 QSize m_sizeSpin;
390
391private:
392 void init(int value, int _base);
393
394protected:
395 virtual void virtual_hook( int id, void* data );
396private:
397 class KIntNumInputPrivate;
398 KIntNumInputPrivate *d;
399};
400
401
402/* ------------------------------------------------------------------------ */
403
404class KDoubleLine;
405
406/**
407 * KDoubleNumInput combines a @ref QSpinBox and optionally a @ref QSlider
408 * with a label to make an easy to use control for setting some float
409 * parameter. This is especially nice for configuration dialogs,
410 * which can have many such combinated controls.
411 *
412 * The slider is created only when the user specifies a range
413 * for the control using the setRange function with the slider
414 * parameter set to "true".
415 *
416 * A special feature of KDoubleNumInput, designed specifically for
417 * the situation when there are several instances in a column,
418 * is that you can specify what portion of the control is taken by the
419 * QSpinBox (the remaining portion is used by the slider). This makes
420 * it very simple to have all the sliders in a column be the same size.
421 *
422 * It uses the @ref KDoubleValidator validator class. KDoubleNumInput
423 * enforces the value to be in the given range, but see the class
424 * documentation of @ref KDoubleSpinBox for the tricky
425 * interrelationship of precision and values. All of what is said
426 * there applies here, too.
427 *
428 * @see KIntNumInput, KDoubleSpinBox
429 * @short An input control for real numbers, consisting of a spinbox and a slider.
430 */
431
432class KDoubleNumInput : public KNumInput
433{
434 Q_OBJECT
435 Q_PROPERTY( double value READ value WRITE setValue )
436 Q_PROPERTY( double minValue READ minValue WRITE setMinValue )
437 Q_PROPERTY( double maxValue READ maxValue WRITE setMaxValue )
438 Q_PROPERTY( QString suffix READ suffix WRITE setSuffix )
439 Q_PROPERTY( QString prefix READ prefix WRITE setPrefix )
440 Q_PROPERTY( QString specialValueText READ specialValueText WRITE setSpecialValueText )
441 Q_PROPERTY( int precision READ precision WRITE setPrecision )
442
443public:
444 /**
445 * Constructs an input control for double values
446 * with initial value 0.00.
447 */
448 KDoubleNumInput(QWidget *parent=0, const char *name=0);
449
450 /**
451 * @deprecated (value is rounded to a multiple of 1/100)
452 * Constructor
453 *
454 * @param value initial value for the control
455 * @param parent parent QWidget
456 * @param name internal name for this widget
457 */
458 KDoubleNumInput(double value, QWidget *parent=0, const char *name=0);
459
460 /**
461 * Constructor
462 *
463 * @param lower lower boundary value
464 * @param upper upper boundary value
465 * @param value initial value for the control
466 * @param step step size to use for up/down arrow clicks
467 * @param precision number of digits after the decimal point
468 * @param parent parent QWidget
469 * @param name internal name for this widget
470 * @since 3.1
471 */
472 KDoubleNumInput(double lower, double upper, double value, double step=0.01,
473 int precision=2, QWidget *parent=0, const char *name=0);
474
475 /**
476 * destructor
477 */
478 virtual ~KDoubleNumInput();
479
480 /**
481 * @deprecated (rounds @p value to a mulitple of 1/100)
482 * Constructor
483 *
484 * puts it below other KNumInput
485 *
486 * @param below
487 * @param value initial value for the control
488 * @param parent parent QWidget
489 * @param name internal name for this widget
490 **/
491 KDoubleNumInput(KNumInput* below, double value, QWidget* parent=0, const char* name=0);
492
493 /**
494 * Constructor
495 *
496 * puts it below other KNumInput
497 *
498 * @param lower lower boundary value
499 * @param upper upper boundary value
500 * @param value initial value for the control
501 * @param step step size to use for up/down arrow clicks
502 * @param precision number of digits after the decimal point
503 * @param parent parent QWidget
504 * @param name internal name for this widget
505 * @since 3.1
506 */
507 KDoubleNumInput(KNumInput* below,
508 double lower, double upper, double value, double step=0.02,
509 int precision=2, QWidget *parent=0, const char *name=0);
510
511 /**
512 * @return the current value.
513 */
514 double value() const;
515
516 /**
517 * @return the suffix.
518 * @see #setSuffix()
519 */
520 QString suffix() const;
521
522 /**
523 * @return the prefix.
524 * @see #setPrefix()
525 */
526 QString prefix() const;
527
528 /**
529 * @return the precision.
530 * @see #setPrecision()
531 */
532 int precision() const;
533
534 /**
535 * @return the string displayed for a special value.
536 * @see #setSpecialValueText()
537 */
538 QString specialValueText() const { return m_specialvalue; }
539
540 /**
541 * @param min minimum value
542 * @param max maximum value
543 * @param step step size for the QSlider
544 */
545 void setRange(double min, double max, double step=1, bool slider=true);
546 /**
547 * Sets the minimum value.
548 */
549 void setMinValue(double min);
550 /**
551 * @return the minimum value.
552 */
553 double minValue() const;
554 /**
555 * Sets the maximum value.
556 */
557 void setMaxValue(double max);
558 /**
559 * @return the maximum value.
560 */
561 double maxValue() const;
562
563 /**
564 * Specifies the number of digits to use.
565 */
566 void setPrecision(int precision);
567
568 /**
569 * @return the reference point for @ref #relativeValue calculation
570 * @since 3.1
571 */
572 double referencePoint() const;
573
574 /**
575 * @return the current value in units of @ref #referencePoint.
576 * @since 3.1
577 */
578 double relativeValue() const;
579
580 /**
581 * Sets the special value text. If set, the spin box will display
582 * this text instead of the numeric value whenever the current
583 * value is equal to @ref #minVal(). Typically this is used for indicating
584 * that the choice has a special (default) meaning.
585 */
586 void setSpecialValueText(const QString& text);
587
588 /**
589 * @reimplemented
590 */
591 virtual void setLabel(const QString & label, int a = AlignLeft | AlignTop);
592 /**
593 * @reimplemented
594 */
595 virtual QSize minimumSizeHint() const;
596 /**
597 * @reimplemented
598 */
599 virtual bool eventFilter(QObject*, QEvent*);
600
601public slots:
602 /**
603 * Sets the value of the control.
604 */
605 void setValue(double);
606
607 /**
608 * Sets the value in units of @ref #referencePoint.
609 * @since 3.1
610 */
611 void setRelativeValue(double);
612
613 /**
614 * Sets the reference Point to @p ref. It @p ref == 0, emitting of
615 * @ref #relativeValueChanged is blocked and @ref #relativeValue
616 * just returns 0.
617 * @since 3.1
618 */
619 void setReferencePoint(double ref);
620
621 /**
622 * Sets the suffix to be displayed to @p suffix. Use QString::null to disable
623 * this feature. Note that the suffix is attached to the value without any
624 * spacing. So if you prefer to display a space separator, set suffix
625 * to something like " cm".
626 * @see #setSuffix()
627 */
628 void setSuffix(const QString &suffix);
629
630 /**
631 * Sets the prefix to be displayed to @p prefix. Use QString::null to disable
632 * this feature. Note that the prefix is attached to the value without any
633 * spacing.
634 * @see #setPrefix()
635 */
636 void setPrefix(const QString &prefix);
637
638signals:
639 /**
640 * Emitted every time the value changes (by calling @ref setValue() or
641 * by user interaction).
642 */
643 void valueChanged(double);
644 /**
645 * This is an overloaded member function, provided for
646 * convenience. It essentially behaves like the above function.
647 *
648 * Contains the value in units of @ref #referencePoint.
649 * @since 3.1
650 */
651 void relativeValueChanged(double);
652
653private slots:
654 void sliderMoved(int);
655 void slotEmitRelativeValueChanged(double);
656
657protected:
658
659 /**
660 * @reimplemented
661 */
662 virtual void doLayout();
663 /**
664 * @reimplemented
665 */
666 void resizeEvent ( QResizeEvent * );
667 virtual void resetEditBox();
668
669 // ### no longer used, remove when BIC allowed
670 KDoubleLine* edit;
671
672 bool m_range;
673 double m_lower, m_upper, m_step;
674 // ### end no longer used
675
676 QSize m_sizeEdit;
677
678 friend class KDoubleLine;
679private:
680 void init(double value, double lower, double upper,
681 double step, int precision);
682 double mapSliderToSpin(int) const;
683 void updateLegacyMembers();
684 // ### no longer used, remove when BIC allowed:
685 QString m_specialvalue, m_prefix, m_suffix;
686 double m_value;
687 short m_precision;
688 // ### end remove when BIC allowed
689
690protected:
691 virtual void virtual_hook( int id, void* data );
692private:
693 class KDoubleNumInputPrivate;
694 KDoubleNumInputPrivate *d;
695};
696
697
698/* ------------------------------------------------------------------------ */
699
700/**
701 * A @ref QSpinBox with support for arbitrary base numbers
702 * (e.g. hexadecimal).
703 *
704 * The class provides an easy interface to use other
705 * numeric systems than the decimal.
706 *
707 * @short A @ref QSpinBox with support for arbitrary base numbers.
708 */
709class KIntSpinBox : public QSpinBox
710{
711 Q_OBJECT
712 Q_PROPERTY( int base READ base WRITE setBase )
713
714public:
715
716 /**
717 * Constructor.
718 *
719 * Constructs a widget with an integer inputline with a little scrollbar
720 * and a slider, with minimal value 0, maximal value 99, step 1, base 10
721 * and initial value 0.
722 */
723 KIntSpinBox( QWidget *parent=0, const char *name=0);
724
725 /**
726 * Constructor.
727 *
728 * Constructs a widget with an integer inputline with a little scrollbar
729 * and a slider.
730 *
731 * @param lower The lowest valid value.
732 * @param upper The greatest valid value.
733 * @param step The step size of the scrollbar.
734 * @param value The actual value.
735 * @param base The base of the used number system.
736 * @param parent The parent of the widget.
737 * @param name The Name of the widget.
738 */
739 KIntSpinBox(int lower, int upper, int step, int value, int base = 10,
740 QWidget* parent = 0, const char* name = 0);
741
742 /**
743 * Destructor.
744 */
745 virtual ~KIntSpinBox();
746
747 /**
748 * Sets the base in which the numbers in the spin box are represented.
749 */
750 void setBase(int base);
751 /**
752 * @return the base in which numbers in the spin box are represented.
753 */
754 int base() const;
755 /**
756 * sets focus and optionally marks all text
757 *
758 */
759 void setEditFocus(bool mark);
760
761protected:
762
763 /**
764 * Overloaded the method in QSpinBox
765 * to make use of the base given in the constructor.
766 */
767 virtual QString mapValueToText(int);
768
769 /**
770 * Overloaded the method in QSpinBox
771 * to make use of the base given in the constructor.
772 */
773 virtual int mapTextToValue(bool*);
774
775private:
776 int val_base;
777protected:
778 virtual void virtual_hook( int id, void* data );
779private:
780 class KIntSpinBoxPrivate;
781 KIntSpinBoxPrivate *d;
782};
783
784
785/* --------------------------------------------------------------------------- */
786
787/**
788 This class provides a spin box for fractional numbers.
789
790 @sect Parameters
791
792 There are a number of interdependent parameters whose relation to
793 each other you need to understand in order to make successful use
794 of the spin box.
795
796 @li precision: The number of decimals after the decimal point.
797 @li maxValue/minValue: upper and lower bound of the valid range
798 @li lineStep: the size of the step that is taken when the user hits
799 the up or down buttons
800
801 Since we work with fixed-point numbers internally, the maximum
802 precision is a function of the valid range and vice versa. More
803 precisely, the following relations hold:
804 <pre>
805 max( abs(minValue()), abs(maxValue() ) <= INT_MAX/10^precision
806 maxPrecision = floor( log10( INT_MAX/max(abs(minValue()),abs(maxValue())) ) )
807 </pre>
808
809 Since the value, bounds and step are rounded to the current
810 precision, you may experience that the order of setting above
811 parameters matters. E.g. the following are @em not equivalent (try
812 it!):
813
814 <pre>
815 // sets precision,
816 // then min/max value (rounded to precison and clipped to obtainable range if needed)
817 // then value and lineStep
818 KDoubleSpinBox * spin = new KDoubleSpinBox( 0, 9.999, 0.001, 4.321, 3, this );
819
820 // sets minValue to 0; maxValue to 10.00(!); value to 4.32(!) and only then
821 // increases the precision - too late, since e.g. value has already been rounded...
822 KDpubleSpinBox * spin = new KDoubleSpinBox( this );
823 spin->setMinValue( 0 );
824 spin->setMaxValue( 9.999 );
825 spin->setValue( 4.321 );
826 spin->setPrecision( 3 );
827 </pre>
828
829 @short A spin box for fractional numbers.
830 @author Marc Mutz <mutz@kde.org>
831 @version $Id$
832 @since 3.1
833**/
834
835class KDoubleSpinBox : public QSpinBox {
836 Q_OBJECT
837 Q_PROPERTY( bool acceptLocalizedNumbers READ acceptLocalizedNumbers WRITE setAcceptLocalizedNumbers )
838 Q_OVERRIDE( double maxValue READ maxValue WRITE setMaxValue )
839 Q_OVERRIDE( double minValue READ minValue WRITE setMinValue )
840 Q_OVERRIDE( double lineStep READ lineStep WRITE setLineStep )
841 Q_OVERRIDE( double value READ value WRITE setValue )
842 Q_PROPERTY( int precision READ precision WRITE setPrecision )
843
844public:
845 /** Constructs a @ref KDoubleSpinBox with parent @p parent and
846 default values for range and value (whatever @ref QRangeControl
847 uses) and precision (2). */
848 KDoubleSpinBox( QWidget * parent=0, const char * name=0 );
849 /** Constructs a @ref KDoubleSpinBox with parent @p parent, range
850 [@p lower,@p upper], @ref lineStep @p step, @ref precision @p
851 precision and initial value @p value. */
852 KDoubleSpinBox( double lower, double upper, double step, double value,
853 int precision=2, QWidget * parent=0, const char * name=0 );
854
855 virtual ~KDoubleSpinBox();
856
857 /** @return whether the spinbox uses localized numbers */
858 bool acceptLocalizedNumbers() const;
859 /** Sets whether to use and accept localized numbers as returned by
860 @ref KLocale::formatNumber() */
861 virtual void setAcceptLocalizedNumbers( bool accept );
862
863 /** Sets a new range for the spin box values. Note that @p lower, @p
864 upper and @p step are rounded to @p precision decimal points
865 first. */
866 void setRange( double lower, double upper, double step=0.01, int precision=2 );
867
868 /** @return the current number of decimal points displayed. */
869 int precision() const;
870 /** Equivalent to @ref setPrecsion( @p precison, @p false ); Needed
871 since Qt's moc doesn't ignore trailing parameters with default
872 args when searching for a property setter method. */
873 void setPrecision( int precision );
874 /** Sets the number of decimal points to use. Note that there is a
875 tradeoff between the precision used and the available range of
876 values. See the class docs for more.
877 @param precision the new number of decimal points to use
878
879 @param force disables checking of bound violations that can
880 arise if you increase the precision so much that the
881 minimum and maximum values can't be represented
882 anymore. Disabling is useful if you don't want to keep
883 the current min and max values anyway. This is what
884 e.g. @ref setRange() does.
885 **/
886 virtual void setPrecision( int precision, bool force );
887
888 /** @return the current value */
889 double value() const;
890 /** @return the current lower bound */
891 double minValue() const;
892 /** Sets the lower bound of the range to @p value, subject to the
893 contraints that @p value is first rounded to the current
894 precision and then clipped to the maximum representable
895 interval.
896 @see maxValue, minValue, setMaxValue, setRange
897 */
898 void setMinValue( double value );
899 /** @return the current upper bound */
900 double maxValue() const;
901 /** Sets the upper bound of the range to @p value, subject to the
902 contraints that @p value is first rounded to the current
903 precision and then clipped to the maximum representable
904 interval.
905 @see minValue, maxValue, setMinValue, setRange
906 */
907 void setMaxValue( double value );
908
909 /** @return the current step size */
910 double lineStep() const;
911 /** Sets the step size for clicking the up/down buttons to @p step,
912 subject to the constraints that @p step is first rounded to the
913 current precision and then clipped to the meaningful interval
914 [1, @p maxValue - @p minValue]. */
915 void setLineStep( double step );
916
917 /** Overridden to ignore any setValidator() calls. */
918 void setValidator( const QValidator * );
919
920signals:
921 /** Emitted whenever @ref QSpinBox::valueChanged( int ) is emitted. */
922 void valueChanged( double value );
923
924public slots:
925 /** Sets the current value to @p value, cubject to the constraints
926 that @p value is frist rounded to the current precision and then
927 clipped to the interval [@p minvalue(),@p maxValue()]. */
928 virtual void setValue( double value );
929
930protected:
931 virtual QString mapValueToText(int);
932 virtual int mapTextToValue(bool*);
933
934protected slots:
935 void slotValueChanged( int value );
936
937protected:
938 virtual void virtual_hook( int id, void* data );
939private:
940 typedef QSpinBox base;
941 void updateValidator();
942 int maxPrecision() const;
943
944 class Private;
945 Private * d;
946};
947
948#endif // K_NUMINPUT_H
diff --git a/microkde/kdeui/knumvalidator.cpp b/microkde/kdeui/knumvalidator.cpp
new file mode 100644
index 0000000..78a8471
--- a/dev/null
+++ b/microkde/kdeui/knumvalidator.cpp
@@ -0,0 +1,372 @@
1/**********************************************************************
2**
3** $Id$
4**
5** KIntValidator, KFloatValidator:
6** Copyright (C) 1999 Glen Parker <glenebob@nwlink.com>
7** KDoubleValidator:
8** Copyright (c) 2002 Marc Mutz <mutz@kde.org>
9**
10** This library is free software; you can redistribute it and/or
11** modify it under the terms of the GNU Library General Public
12** License as published by the Free Software Foundation; either
13** version 2 of the License, or (at your option) any later version.
14**
15** This library is distributed in the hope that it will be useful,
16** but WITHOUT ANY WARRANTY; without even the implied warranty of
17** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18** Library General Public License for more details.
19**
20** You should have received a copy of the GNU Library General Public
21** License along with this library; if not, write to the Free
22** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23**
24*****************************************************************************/
25
26#include <qwidget.h>
27#include <qstring.h>
28
29#include "knumvalidator.h"
30#include <klocale.h>
31#include <kglobal.h>
32#include <kdebug.h>
33
34///////////////////////////////////////////////////////////////
35// Implementation of KIntValidator
36//
37
38KIntValidator::KIntValidator ( QWidget * parent, int base, const char * name )
39 : QValidator(parent, name)
40{
41 _base = base;
42 if (_base < 2) _base = 2;
43 if (_base > 36) _base = 36;
44
45 _min = _max = 0;
46}
47
48KIntValidator::KIntValidator ( int bottom, int top, QWidget * parent, int base, const char * name )
49 : QValidator(parent, name)
50{
51 _base = base;
52 if (_base > 36) _base = 36;
53
54 _min = bottom;
55 _max = top;
56}
57
58KIntValidator::~KIntValidator ()
59{}
60
61QValidator::State KIntValidator::validate ( QString &str, int & ) const
62{
63 bool ok;
64 int val = 0;
65 QString newStr;
66
67 newStr = str.stripWhiteSpace();
68 if (_base > 10)
69 newStr = newStr.upper();
70
71 if (newStr == QString::fromLatin1("-")) // a special case
72 if ((_min || _max) && _min >= 0)
73 ok = false;
74 else
75 return QValidator::Acceptable;
76 else if (newStr.length())
77 val = newStr.toInt(&ok, _base);
78 else {
79 val = 0;
80 ok = true;
81 }
82
83 if (! ok)
84 return QValidator::Invalid;
85
86 if ((! _min && ! _max) || (val >= _min && val <= _max))
87 return QValidator::Acceptable;
88
89 if (_max && _min >= 0 && val < 0)
90 return QValidator::Invalid;
91
92 return QValidator::Valid;
93}
94
95void KIntValidator::fixup ( QString &str ) const
96{
97 int dummy;
98 int val;
99 QValidator::State state;
100
101 state = validate(str, dummy);
102
103 if (state == QValidator::Invalid || state == QValidator::Acceptable)
104 return;
105
106 if (! _min && ! _max)
107 return;
108
109 val = str.toInt(0, _base);
110
111 if (val < _min) val = _min;
112 if (val > _max) val = _max;
113
114 str.setNum(val, _base);
115}
116
117void KIntValidator::setRange ( int bottom, int top )
118{
119 _min = bottom;
120 _max = top;
121
122 if (_max < _min)
123 _max = _min;
124}
125
126void KIntValidator::setBase ( int base )
127{
128 _base = base;
129 if (_base < 2) _base = 2;
130}
131
132int KIntValidator::bottom () const
133{
134 return _min;
135}
136
137int KIntValidator::top () const
138{
139 return _max;
140}
141
142int KIntValidator::base () const
143{
144 return _base;
145}
146
147
148///////////////////////////////////////////////////////////////
149// Implementation of KFloatValidator
150//
151
152class KFloatValidatorPrivate
153{
154public:
155 KFloatValidatorPrivate()
156 {
157 }
158 ~KFloatValidatorPrivate()
159 {
160 }
161 bool acceptLocalizedNumbers;
162};
163
164
165KFloatValidator::KFloatValidator ( QWidget * parent, const char * name )
166 : QValidator(parent, name)
167{
168 d = new KFloatValidatorPrivate;
169 d->acceptLocalizedNumbers=false;
170 _min = _max = 0;
171}
172
173KFloatValidator::KFloatValidator ( double bottom, double top, QWidget * parent, const char * name )
174 : QValidator(parent, name)
175{
176 d = new KFloatValidatorPrivate;
177 d->acceptLocalizedNumbers=false;
178 _min = bottom;
179 _max = top;
180}
181
182KFloatValidator::KFloatValidator ( double bottom, double top, bool localeAware, QWidget * parent, const char * name )
183 : QValidator(parent, name)
184{
185 d = new KFloatValidatorPrivate;
186 d->acceptLocalizedNumbers = localeAware;
187 _min = bottom;
188 _max = top;
189}
190
191KFloatValidator::~KFloatValidator ()
192{
193 delete d;
194}
195
196void KFloatValidator::setAcceptLocalizedNumbers(bool _b)
197{
198 d->acceptLocalizedNumbers=_b;
199}
200
201bool KFloatValidator::acceptLocalizedNumbers() const
202{
203 return d->acceptLocalizedNumbers;
204}
205
206QValidator::State KFloatValidator::validate ( QString &str, int & ) const
207{
208 bool ok;
209 double val = 0;
210 QString newStr;
211 newStr = str.stripWhiteSpace();
212
213 if (newStr == QString::fromLatin1("-")) // a special case
214 if ((_min || _max) && _min >= 0)
215 ok = false;
216 else
217 return QValidator::Acceptable;
218 else if (newStr == QString::fromLatin1(".") || (d->acceptLocalizedNumbers && newStr==KGlobal::locale()->decimalSymbol())) // another special case
219 return QValidator::Acceptable;
220 else if (newStr.length())
221 {
222 val = newStr.toDouble(&ok);
223 if(!ok && d->acceptLocalizedNumbers)
224 val= KGlobal::locale()->readNumber(newStr,&ok);
225 }
226 else {
227 val = 0;
228 ok = true;
229 }
230
231 if (! ok)
232 return QValidator::Invalid;
233
234 if (( !_min && !_max) || (val >= _min && val <= _max))
235 return QValidator::Acceptable;
236
237 if (_max && _min >= 0 && val < 0)
238 return QValidator::Invalid;
239
240 if ( (_min || _max) && (val < _min || val > _max))
241 return QValidator::Invalid;
242
243 return QValidator::Valid;
244}
245
246void KFloatValidator::fixup ( QString &str ) const
247{
248 int dummy;
249 double val;
250 QValidator::State state;
251
252 state = validate(str, dummy);
253
254 if (state == QValidator::Invalid || state == QValidator::Acceptable)
255 return;
256
257 if (! _min && ! _max)
258 return;
259
260 val = str.toDouble();
261
262 if (val < _min) val = _min;
263 if (val > _max) val = _max;
264
265 str.setNum(val);
266}
267
268void KFloatValidator::setRange ( double bottom, double top )
269{
270 _min = bottom;
271 _max = top;
272
273 if (_max < _min)
274 _max = _min;
275}
276
277double KFloatValidator::bottom () const
278{
279 return _min;
280}
281
282double KFloatValidator::top () const
283{
284 return _max;
285}
286
287
288
289
290///////////////////////////////////////////////////////////////
291// Implementation of KDoubleValidator
292//
293
294class KDoubleValidator::Private {
295public:
296 Private( bool accept=true ) : acceptLocalizedNumbers( accept ) {}
297
298 bool acceptLocalizedNumbers;
299};
300
301KDoubleValidator::KDoubleValidator( QObject * parent, const char * name )
302 : QDoubleValidator( (QWidget*)parent, name ), d( 0 )
303{
304 d = new Private();
305}
306
307KDoubleValidator::KDoubleValidator( double bottom, double top, int decimals,
308 QObject * parent, const char * name )
309 : QDoubleValidator( bottom, top, decimals, (QWidget*)parent, name ), d( 0 )
310{
311 d = new Private();
312}
313
314KDoubleValidator::~KDoubleValidator()
315{
316 delete d;
317}
318
319bool KDoubleValidator::acceptLocalizedNumbers() const {
320 return d->acceptLocalizedNumbers;
321}
322
323void KDoubleValidator::setAcceptLocalizedNumbers( bool accept ) {
324 d->acceptLocalizedNumbers = accept;
325}
326
327QValidator::State KDoubleValidator::validate( QString & input, int & p ) const {
328 QString s = input;
329 if ( acceptLocalizedNumbers() ) {
330 KLocale * l = KGlobal::locale();
331 // ok, we have to re-format the number to have:
332 // 1. decimalSymbol == '.'
333 // 2. negativeSign == '-'
334 // 3. positiveSign == <empty>
335 // 4. thousandsSeparator() == <empty> (we don't check that there
336 // are exactly three decimals between each separator):
337 QString d = l->decimalSymbol(),
338 n = l->negativeSign(),
339 p = l->positiveSign(),
340 t = l->thousandsSeparator();
341 // first, delete p's and t's:
342 if ( !p.isEmpty() )
343 for ( int idx = s.find( p ) ; idx >= 0 ; idx = s.find( p, idx ) )
344 s.remove( idx, p.length() );
345
346
347 if ( !t.isEmpty() )
348 for ( int idx = s.find( t ) ; idx >= 0 ; idx = s.find( t, idx ) )
349 s.remove( idx, t.length() );
350
351 // then, replace the d's and n's
352 if ( ( !n.isEmpty() && n.find('.') != -1 ) ||
353 ( !d.isEmpty() && d.find('-') != -1 ) ) {
354 // make sure we don't replace something twice:
355 kdWarning() << "KDoubleValidator: decimal symbol contains '-' or "
356 "negative sign contains '.' -> improve algorithm" << endl;
357 return Invalid;
358 }
359
360 if ( !d.isEmpty() && d != "." )
361 for ( int idx = s.find( d ) ; idx >= 0 ; idx = s.find( d, idx + 1 ) )
362 s.replace( idx, d.length(), ".");
363
364 if ( !n.isEmpty() && n != "-" )
365 for ( int idx = s.find( n ) ; idx >= 0 ; idx = s.find( n, idx + 1 ) )
366 s.replace( idx, n.length(), "-" );
367 }
368
369 return base::validate( s, p );
370}
371
372//US #include "knumvalidator.moc"
diff --git a/microkde/kdeui/knumvalidator.h b/microkde/kdeui/knumvalidator.h
new file mode 100644
index 0000000..2f0a937
--- a/dev/null
+++ b/microkde/kdeui/knumvalidator.h
@@ -0,0 +1,209 @@
1/**********************************************************************
2**
3** $Id$
4**
5** Copyright (C) 1999 Glen Parker <glenebob@nwlink.com>
6** Copyright (C) 2002 Marc Mutz <mutz@kde.org>
7**
8** This library is free software; you can redistribute it and/or
9** modify it under the terms of the GNU Library General Public
10** License as published by the Free Software Foundation; either
11** version 2 of the License, or (at your option) any later version.
12**
13** This library is distributed in the hope that it will be useful,
14** but WITHOUT ANY WARRANTY; without even the implied warranty of
15** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16** Library General Public License for more details.
17**
18** You should have received a copy of the GNU Library General Public
19** License along with this library; if not, write to the Free
20** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21**
22*****************************************************************************/
23
24#ifndef __KNUMVALIDATOR_H
25#define __KNUMVALIDATOR_H
26
27#include <qvalidator.h>
28
29class QWidget;
30class QString;
31
32/**
33 * @ref QValidator for integers.
34
35 This can be used by @ref QLineEdit or subclass to provide validated
36 text entry. Can be provided with a base value (default is 10), to allow
37 the proper entry of hexadecimal, octal, or any other base numeric data.
38
39 @author Glen Parker <glenebob@nwlink.com>
40 @version 0.0.1
41*/
42class KIntValidator : public QValidator {
43
44 public:
45 /**
46 Constuctor. Also sets the base value.
47 */
48 KIntValidator ( QWidget * parent, int base = 10, const char * name = 0 );
49 /**
50 * Constructor. Also sets the minimum, maximum, and numeric base values.
51 */
52 KIntValidator ( int bottom, int top, QWidget * parent, int base = 10, const char * name = 0 );
53 /**
54 * Destructs the validator.
55 */
56 virtual ~KIntValidator ();
57 /**
58 * Validates the text, and return the result. Does not modify the parameters.
59 */
60 virtual State validate ( QString &, int & ) const;
61 /**
62 * Fixes the text if possible, providing a valid string. The parameter may be modified.
63 */
64 virtual void fixup ( QString & ) const;
65 /**
66 * Sets the minimum and maximum values allowed.
67 */
68 virtual void setRange ( int bottom, int top );
69 /**
70 * Sets the numeric base value.
71 */
72 virtual void setBase ( int base );
73 /**
74 * Returns the current minimum value allowed.
75 */
76 virtual int bottom () const;
77 /**
78 * Returns the current maximum value allowed.
79 */
80 virtual int top () const;
81 /**
82 * Returns the current numeric base.
83 */
84 virtual int base () const;
85
86 private:
87 int _base;
88 int _min;
89 int _max;
90
91};
92
93class KFloatValidatorPrivate;
94
95/**
96 @obsolete Use @ref KDoubleValidator
97
98 @ref QValidator for floating point entry.
99 Extends the QValidator class to properly validate double numeric data.
100 This can be used by @ref QLineEdit or subclass to provide validated
101 text entry.
102
103 @author Glen Parker <glenebob@nwlink.com>
104 @version 0.0.1
105*/
106class KFloatValidator : public QValidator {
107
108 public:
109 /**
110 * Constructor.
111 */
112 KFloatValidator ( QWidget * parent, const char * name = 0 );
113 /**
114 * Constructor. Also sets the minimum and maximum values.
115 */
116 KFloatValidator ( double bottom, double top, QWidget * parent, const char * name = 0 );
117 /**
118 * Constructor. Sets the validator to be locale aware if @p localeAware is true.
119 */
120 KFloatValidator ( double bottom, double top, bool localeAware, QWidget * parent, const char * name = 0 );
121 /**
122 * Destructs the validator.
123 */
124 virtual ~KFloatValidator ();
125 /**
126 * Validates the text, and return the result. Does not modify the parameters.
127 */
128 virtual State validate ( QString &, int & ) const;
129 /**
130 * Fixes the text if possible, providing a valid string. The parameter may be modified.
131 */
132 virtual void fixup ( QString & ) const;
133 /**
134 * Sets the minimum and maximum value allowed.
135 */
136 virtual void setRange ( double bottom, double top );
137 /**
138 * Returns the current minimum value allowed.
139 */
140 virtual double bottom () const;
141 /**
142 * Returns the current maximum value allowed.
143 */
144 virtual double top () const;
145 /**
146 * Sets the validator to be locale aware if @p is true. In this case, the
147 * character KLocale::decimalSymbol() from the global locale is recognized
148 * as decimal separator.
149 */
150 void setAcceptLocalizedNumbers(bool b);
151 /**
152 * Returns true if the validator is locale aware.
153 * @see setAcceptLocalizedNumbers().
154 */
155 bool acceptLocalizedNumbers() const;
156
157 private:
158 double _min;
159 double _max;
160
161 KFloatValidatorPrivate *d;
162};
163
164/**
165 KDoubleValidator extends @ref QDoubleValidator to be
166 locale-aware. That means that - subject to not being disabled -
167 @ref KLocale::decimalPoint(), @ref KLocale::thousandsSeparator()
168 and @ref KLocale::positiveSign() and @ref KLocale::negativeSign()
169 are respected.
170
171 @short A locale-aware @ref QDoubleValidator
172 @author Marc Mutz <mutz@kde.org>
173 @version $Id$
174 @see KIntValidator
175 @since 3.1
176**/
177
178class KDoubleValidator : public QDoubleValidator {
179 Q_OBJECT
180 Q_PROPERTY( bool acceptLocalizedNumbers READ acceptLocalizedNumbers WRITE setAcceptLocalizedNumbers )
181public:
182 /** Constuct a locale-aware KDoubleValidator with default range
183 (whatever @ref QDoubleValidator uses for that) and parent @p
184 parent */
185 KDoubleValidator( QObject * parent, const char * name=0 );
186 /** Constuct a locale-aware KDoubleValidator for range [@p bottom,@p
187 top] and a precision of @p decimals decimals after the decimal
188 point. */
189 KDoubleValidator( double bottom, double top, int decimals,
190 QObject * parent, const char * name=0 );
191 /** Destructs the validator.
192 */
193 virtual ~KDoubleValidator();
194
195 /** Overloaded for internal reasons. The API is not affected. */
196 virtual QValidator::State validate( QString & input, int & pos ) const;
197
198 /** @return whether localized numbers are accepted (default: true) */
199 bool acceptLocalizedNumbers() const;
200 /** Sets whether to accept localized numbers (default: true) */
201 void setAcceptLocalizedNumbers( bool accept );
202
203private:
204 typedef QDoubleValidator base;
205 class Private;
206 Private * d;
207};
208
209#endif
diff --git a/microkde/kdeui/kseparator.cpp b/microkde/kdeui/kseparator.cpp
new file mode 100644
index 0000000..d028420
--- a/dev/null
+++ b/microkde/kdeui/kseparator.cpp
@@ -0,0 +1,121 @@
1/*
2 * Copyright (C) 1997 Michael Roth <mroth@wirlweb.de>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Library General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 *
18 */
19
20#include <qstyle.h>
21
22#include <kdebug.h>
23//US #include <kapplication.h>
24
25//US #include "kseparator.moc"
26
27#include "kseparator.h"
28
29KSeparator::KSeparator(QWidget* parent, const char* name, WFlags f)
30 : QFrame(parent, name, f)
31{
32 setLineWidth(1);
33 setMidLineWidth(0);
34 setOrientation( HLine );
35}
36
37
38
39KSeparator::KSeparator(int orientation, QWidget* parent, const char* name, WFlags f)
40 : QFrame(parent, name, f)
41{
42 setLineWidth(1);
43 setMidLineWidth(0);
44 setOrientation( orientation );
45}
46
47
48
49void KSeparator::setOrientation(int orientation)
50{
51 switch(orientation)
52 {
53 case Vertical:
54 case VLine:
55 setFrameStyle( QFrame::VLine | QFrame::Sunken );
56 setMinimumSize(2, 0);
57 break;
58
59 default:
60 kdWarning() << "KSeparator::setOrientation(): invalid orientation, using default orientation HLine" << endl;
61
62 case Horizontal:
63 case HLine:
64 setFrameStyle( QFrame::HLine | QFrame::Sunken );
65 setMinimumSize(0, 2);
66 break;
67 }
68}
69
70
71
72int KSeparator::orientation() const
73{
74 if ( frameStyle() & VLine )
75 return VLine;
76
77 if ( frameStyle() & HLine )
78 return HLine;
79
80 return 0;
81}
82
83void KSeparator::drawFrame(QPainter *p)
84{
85 QPointp1, p2;
86 QRectr = frameRect();
87 const QColorGroup & g = colorGroup();
88
89 if ( frameStyle() & HLine ) {
90 p1 = QPoint( r.x(), r.height()/2 );
91 p2 = QPoint( r.x()+r.width(), p1.y() );
92 }
93 else {
94 p1 = QPoint( r.x()+r.width()/2, 0 );
95 p2 = QPoint( p1.x(), r.height() );
96 }
97
98/*US
99 QStyleOption opt( lineWidth(), midLineWidth() );
100 style().drawPrimitive( QStyle::PE_Separator, p, QRect( p1, p2 ), g,
101 QStyle::Style_Sunken, opt );
102*/
103//LRstyle().drawSeparator( p, p1.x(), p1.y(), p2.x(), p2.y(), g, true, lineWidth(), midLineWidth());
104
105}
106
107
108QSize KSeparator::sizeHint() const
109{
110 if ( frameStyle() & VLine )
111 return QSize(2, 0);
112
113 if ( frameStyle() & HLine )
114 return QSize(0, 2);
115
116 return QSize(-1, -1);
117}
118
119void KSeparator::virtual_hook( int, void* )
120{ /*BASE::virtual_hook( id, data );*/ }
121
diff --git a/microkde/kdeui/kseparator.h b/microkde/kdeui/kseparator.h
new file mode 100644
index 0000000..6d2712a
--- a/dev/null
+++ b/microkde/kdeui/kseparator.h
@@ -0,0 +1,77 @@
1/*
2 * Copyright (C) 1997 Michael Roth <mroth@wirlweb.de>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Library General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 *
18 */
19
20#ifndef __KSEPARATOR_H__
21#define __KSEPARATOR_H__
22
23#include <qframe.h>
24
25/**
26 * Standard horizontal or vertical separator.
27 *
28 * @author Michael Roth <mroth@wirlweb.de>
29 * @version $Id$
30*/
31class KSeparator : public QFrame
32{
33 Q_OBJECT
34 Q_PROPERTY( int orientation READ orientation WRITE setOrientation )
35 public:
36 /**
37 * Constructor.
38 **/
39 KSeparator(QWidget* parent=0, const char* name=0, WFlags f=0);
40 /**
41 * Constructor.
42 *
43 * @param orientation Set the orientation of the separator.
44 * Possible values are HLine or Horizontal and VLine or Vertical.
45 **/
46 KSeparator(int orientation, QWidget* parent=0, const char* name=0,
47 WFlags f=0);
48
49 /**
50 * Returns the orientation of the separator.
51 *
52 * Possible values are VLine and HLine.
53 **/
54 int orientation() const;
55
56 /**
57 * Set the orientation of the separator to @p orient
58 *
59 * Possible values are VLine and HLine.
60 */
61 void setOrientation(int orient);
62
63 /**
64 * The recommended height (width) for a horizontal (vertical) separator.
65 **/
66 virtual QSize sizeHint() const;
67
68protected:
69 virtual void drawFrame( QPainter * );
70protected:
71 virtual void virtual_hook( int id, void* data );
72private:
73 class KSeparatorPrivate* d;
74};
75
76
77#endif // __KSEPARATOR_H__
diff --git a/microkde/kdeui/ksqueezedtextlabel.cpp b/microkde/kdeui/ksqueezedtextlabel.cpp
new file mode 100644
index 0000000..37fa29a
--- a/dev/null
+++ b/microkde/kdeui/ksqueezedtextlabel.cpp
@@ -0,0 +1,107 @@
1/* This file is part of the KDE libraries
2 Copyright (C) 2000 Ronny Standtke <Ronny.Standtke@gmx.de>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License version 2 as published by the Free Software Foundation.
7
8 This library is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 Library General Public License for more details.
12
13 You should have received a copy of the GNU Library General Public License
14 along with this library; see the file COPYING.LIB. If not, write to
15 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16 Boston, MA 02111-1307, USA.
17*/
18
19#include "ksqueezedtextlabel.h"
20#include <qtooltip.h>
21
22KSqueezedTextLabel::KSqueezedTextLabel( const QString &text , QWidget *parent, const char *name )
23 : QLabel ( parent, name ) {
24 setSizePolicy(QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ));
25 fullText = text;
26 squeezeTextToLabel();
27}
28
29KSqueezedTextLabel::KSqueezedTextLabel( QWidget *parent, const char *name )
30 : QLabel ( parent, name ) {
31 setSizePolicy(QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ));
32}
33
34void KSqueezedTextLabel::resizeEvent( QResizeEvent * ) {
35 squeezeTextToLabel();
36}
37
38QSize KSqueezedTextLabel::minimumSizeHint() const
39{
40 QSize sh = QLabel::minimumSizeHint();
41 sh.setWidth(-1);
42 return sh;
43}
44
45void KSqueezedTextLabel::setText( const QString &text ) {
46 fullText = text;
47 squeezeTextToLabel();
48}
49
50void KSqueezedTextLabel::squeezeTextToLabel() {
51 QFontMetrics fm(fontMetrics());
52 int labelWidth = size().width();
53 int textWidth = fm.width(fullText);
54 if (textWidth > labelWidth) {
55 // start with the dots only
56 QString squeezedText = "...";
57 int squeezedWidth = fm.width(squeezedText);
58
59 // estimate how many letters we can add to the dots on both sides
60 int letters = fullText.length() * (labelWidth - squeezedWidth) / textWidth / 2;
61 if (labelWidth < squeezedWidth) letters=1;
62 squeezedText = fullText.left(letters) + "..." + fullText.right(letters);
63 squeezedWidth = fm.width(squeezedText);
64
65 if (squeezedWidth < labelWidth) {
66 // we estimated too short
67 // add letters while text < label
68 do {
69 letters++;
70 squeezedText = fullText.left(letters) + "..." + fullText.right(letters);
71 squeezedWidth = fm.width(squeezedText);
72 } while (squeezedWidth < labelWidth);
73 letters--;
74 squeezedText = fullText.left(letters) + "..." + fullText.right(letters);
75 } else if (squeezedWidth > labelWidth) {
76 // we estimated too long
77 // remove letters while text > label
78 do {
79 letters--;
80 squeezedText = fullText.left(letters) + "..." + fullText.right(letters);
81 squeezedWidth = fm.width(squeezedText);
82 } while (letters && squeezedWidth > labelWidth);
83 }
84
85 if (letters < 5) {
86 // too few letters added -> we give up squeezing
87 QLabel::setText(fullText);
88 } else {
89 QLabel::setText(squeezedText);
90 }
91
92//US QToolTip::remove( this );
93//US QToolTip::add( this, fullText );
94
95 } else {
96 QLabel::setText(fullText);
97
98//US QToolTip::remove( this );
99//US QToolTip::hide();
100
101 };
102}
103
104void KSqueezedTextLabel::virtual_hook( int, void* )
105{ /*BASE::virtual_hook( id, data );*/ }
106
107//US #include "ksqueezedtextlabel.moc"
diff --git a/microkde/kdeui/ksqueezedtextlabel.h b/microkde/kdeui/ksqueezedtextlabel.h
new file mode 100644
index 0000000..1634adc
--- a/dev/null
+++ b/microkde/kdeui/ksqueezedtextlabel.h
@@ -0,0 +1,76 @@
1/* This file is part of the KDE libraries
2 Copyright (C) 2000 Ronny Standtke <Ronny.Standtke@gmx.de>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License version 2 as published by the Free Software Foundation.
7
8 This library is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 Library General Public License for more details.
12
13 You should have received a copy of the GNU Library General Public License
14 along with this library; see the file COPYING.LIB. If not, write to
15 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16 Boston, MA 02111-1307, USA.
17*/
18
19#ifndef KSQUEEZEDTEXTLABEL_H
20#define KSQUEEZEDTEXTLABEL_H
21
22#include <qlabel.h>
23
24/**
25 * A label class that squeezes its text into the label
26 *
27 * If the text is too long to fit into the label it is divided into
28 * remaining left and right parts which are separated by three dots.
29 *
30 * Example:
31 * http://www.kde.org/documentation/index.html could be squeezed to
32 * http://www.kde...ion/index.html
33
34 * @short A replacement for QLabel that squeezes its text
35 * @author Ronny Standtke <Ronny.Standtke@gmx.de>
36 * @version $Id$
37 *
38 */
39
40/*
41 * @ref QLabel
42 */
43class KSqueezedTextLabel : public QLabel {
44 Q_OBJECT
45
46public:
47 /**
48 * Default constructor.
49 */
50 KSqueezedTextLabel( QWidget *parent, const char *name = 0 );
51 KSqueezedTextLabel( const QString &text, QWidget *parent, const char *name = 0 );
52
53 virtual QSize minimumSizeHint() const;
54
55public slots:
56 void setText( const QString & );
57
58protected:
59 /**
60 * used when widget is resized
61 */
62 void resizeEvent( QResizeEvent * );
63 /**
64 * does the dirty work
65 */
66 void squeezeTextToLabel();
67 QString fullText;
68
69protected:
70 virtual void virtual_hook( int id, void* data );
71private:
72 class KSqueezedTextLabelPrivate;
73 KSqueezedTextLabelPrivate *d;
74};
75
76#endif // KSQUEEZEDTEXTLABEL_H
diff --git a/microkde/kdeui/kstdaction.cpp b/microkde/kdeui/kstdaction.cpp
new file mode 100644
index 0000000..cfd7b54
--- a/dev/null
+++ b/microkde/kdeui/kstdaction.cpp
@@ -0,0 +1,362 @@
1/* This file is part of the KDE libraries
2 Copyright (C) 1999,2000 Kurt Granroth <granroth@kde.org>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License version 2 as published by the Free Software Foundation.
7
8 This library is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 Library General Public License for more details.
12
13 You should have received a copy of the GNU Library General Public License
14 along with this library; see the file COPYING.LIB. If not, write to
15 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16 Boston, MA 02111-1307, USA.
17*/
18
19#include "kstdaction.h"
20
21#include <qtoolbutton.h>
22#include <qwhatsthis.h>
23
24//US #include <kaboutdata.h>
25#include <kaction.h>
26#include <kapplication.h>
27#include <kdebug.h>
28#include <kglobal.h>
29#include <kiconloader.h>
30#include <klocale.h>
31//US #include <kstdaccel.h>
32//US #include <kmainwindow.h>
33
34namespace KStdAction
35{
36
37struct KStdActionInfo
38{
39 StdAction id;
40 /*USKStdAccel::StdAccel idAccel;*/
41 const char* psName;
42 const char* psLabel;
43 const char* psWhatsThis;
44 const char* psIconName;
45};
46
47const KStdActionInfo g_rgActionInfo[] =
48{
49 { New, /*USKStdAccel::New,*/ "file_new", I18N_NOOP("&New"), 0, "filenew" },
50 { Open, /*USKStdAccel::Open,*/ "file_open", I18N_NOOP("&Open..."), 0, "fileopen" },
51 { OpenRecent, /*USKStdAccel::AccelNone,*/ "file_open_recent", I18N_NOOP("Open &Recent"), 0, 0 },
52 { Save, /*USKStdAccel::Save,*/ "file_save", I18N_NOOP("&Save"), 0, "filesave" },
53 { SaveAs, /*USKStdAccel::AccelNone,*/ "file_save_as", I18N_NOOP("Save &As..."), 0, "filesaveas" },
54 { Revert, /*USKStdAccel::AccelNone,*/ "file_revert", I18N_NOOP("Re&vert"), 0, "revert" },
55 { Close, /*USKStdAccel::Close,*/ "file_close", I18N_NOOP("&Close"), 0, "fileclose" },
56 { Print, /*USKStdAccel::Print,*/ "file_print", I18N_NOOP("&Print..."), 0, "fileprint" },
57 { PrintPreview, /*USKStdAccel::AccelNone,*/ "file_print_preview", I18N_NOOP("Print Previe&w..."), 0, "filequickprint" },
58 { Mail, /*USKStdAccel::AccelNone,*/ "file_mail", I18N_NOOP("&Mail..."), 0, "mail_send" },
59 { Quit, /*USKStdAccel::Quit,*/ "file_quit", I18N_NOOP("&Exit"), 0, "exit" },
60
61 { Undo, /*USKStdAccel::Undo,*/ "edit_undo", I18N_NOOP("&Undo"), 0, "undo" },
62 { Redo, /*USKStdAccel::Redo,*/ "edit_redo", I18N_NOOP("Re&do"), 0, "redo" },
63 { Cut, /*USKStdAccel::Cut,*/ "edit_cut", I18N_NOOP("Cu&t"), 0, "editcut" },
64 { Copy, /*USKStdAccel::Copy,*/ "edit_copy", I18N_NOOP("&Copy"), 0, "editcopy" },
65 { Paste, /*USKStdAccel::Paste,*/ "edit_paste", I18N_NOOP("&Paste"), 0, "editpaste" },
66 { SelectAll, /*USKStdAccel::SelectAll,*/ "edit_select_all", I18N_NOOP("Select &All"), 0, 0 },
67 { Deselect, /*USKStdAccel::Deselect,*/ "edit_deselect", I18N_NOOP("Dese&lect"), 0, 0 },
68 { Find, /*USKStdAccel::Find,*/ "edit_find", I18N_NOOP("&Find..."), 0, "find" },
69 { FindNext, /*USKStdAccel::FindNext,*/ "edit_find_next", I18N_NOOP("Find &Next"), 0, "next" },
70 // FIXME: rename edit_find_last to edit_find_prev for KDE 4
71 { FindPrev, /*USKStdAccel::FindPrev,*/ "edit_find_last", I18N_NOOP("Find Pre&vious"), 0, "previous" },
72 { Replace, /*USKStdAccel::Replace,*/ "edit_replace", I18N_NOOP("&Replace..."), 0, 0 },
73
74 { ActualSize, /*USKStdAccel::AccelNone,*/ "view_actual_size", I18N_NOOP("&Actual Size"), 0, 0 },
75 { FitToPage, /*USKStdAccel::AccelNone,*/ "view_fit_to_page", I18N_NOOP("&Fit to Page"), 0, 0 },
76 { FitToWidth, /*USKStdAccel::AccelNone,*/ "view_fit_to_width", I18N_NOOP("Fit to Page &Width"), 0, 0 },
77 { FitToHeight, /*USKStdAccel::AccelNone,*/ "view_fit_to_height", I18N_NOOP("Fit to Page &Height"), 0, 0 },
78 { ZoomIn, /*USKStdAccel::ZoomIn,*/ "view_zoom_in", I18N_NOOP("Zoom &In"), 0, "viewmag+" },
79 { ZoomOut, /*USKStdAccel::ZoomOut,*/ "view_zoom_out", I18N_NOOP("Zoom &Out"), 0, "viewmag-" },
80 { Zoom, /*USKStdAccel::AccelNone,*/ "view_zoom", I18N_NOOP("&Zoom..."), 0, "viewmag" },
81 { Redisplay, /*USKStdAccel::AccelNone,*/ "view_redisplay", I18N_NOOP("&Redisplay"), 0, "reload" },
82
83 { Up, /*USKStdAccel::Up,*/ "go_up", I18N_NOOP("&Up"), 0, "up" },
84 // The following three have special i18n() needs for sLabel
85 { Back, /*USKStdAccel::Back,*/ "go_back", 0, 0, "back" },
86 { Forward, /*USKStdAccel::Forward,*/ "go_forward", 0, 0, "forward" },
87 { Home, /*USKStdAccel::Home,*/ "go_home", 0, 0, "gohome" },
88 { Prior, /*USKStdAccel::Prior,*/ "go_previous", I18N_NOOP("&Previous Page"), 0, "previous" },
89 { Next, /*USKStdAccel::Next,*/ "go_next", I18N_NOOP("&Next Page"), 0, "next" },
90 { Goto, /*USKStdAccel::AccelNone,*/ "go_goto", I18N_NOOP("&Go To..."), 0, 0 },
91 { GotoPage, /*USKStdAccel::AccelNone,*/ "go_goto_page", I18N_NOOP("&Go to Page..."), 0, "goto" },
92 { GotoLine, /*USKStdAccel::GotoLine,*/ "go_goto_line", I18N_NOOP("&Go to Line..."), 0, 0 },
93 { FirstPage, /*USKStdAccel::Home,*/ "go_first", I18N_NOOP("&First Page"), 0, "top" },
94 { LastPage, /*USKStdAccel::End,*/ "go_last", I18N_NOOP("&Last Page"), 0, "bottom" },
95
96 { AddBookmark, /*USKStdAccel::AddBookmark,*/ "bookmark_add", I18N_NOOP("&Add Bookmark"), 0, "bookmark_add" },
97 { EditBookmarks, /*USKStdAccel::AccelNone,*/ "bookmark_edit", I18N_NOOP("&Edit Bookmarks"), 0, "bookmark" },
98
99 { Spelling, /*USKStdAccel::AccelNone,*/ "tools_spelling", I18N_NOOP("&Spelling..."), 0, "spellcheck" },
100
101 { ShowMenubar, /*USKStdAccel::ShowMenubar,*/ "options_show_menubar", I18N_NOOP("Show &Menubar"), 0, "showmenu" },
102 { ShowToolbar, /*USKStdAccel::AccelNone,*/ "options_show_toolbar", I18N_NOOP("Show &Toolbar"), 0, 0 },
103 { ShowStatusbar, /*USKStdAccel::AccelNone,*/ "options_show_statusbar", I18N_NOOP("Show St&atusbar"), 0, 0 },
104 { SaveOptions, /*USKStdAccel::AccelNone,*/ "options_save_options", I18N_NOOP("&Save Settings"), 0, 0 },
105 { KeyBindings, /*USKStdAccel::AccelNone,*/ "options_configure_keybinding", I18N_NOOP("Configure S&hortcuts..."), 0,"configure_shortcuts" },
106 { Preferences, /*USKStdAccel::AccelNone,*/ "options_configure", I18N_NOOP("&Configure %1..."), 0, "configure" },
107 { ConfigureToolbars, /*USKStdAccel::AccelNone,*/ "options_configure_toolbars", I18N_NOOP("Configure Tool&bars..."), 0,"configure_toolbars" },
108 { ConfigureNotifications, /*USKStdAccel::AccelNone,*/ "options_configure_notifications", I18N_NOOP("Configure &Notifications..."), 0, "knotify" },
109
110 { Help, /*USKStdAccel::Help,*/ "help", 0, 0, "help" },
111 { HelpContents, /*USKStdAccel::AccelNone,*/ "help_contents", I18N_NOOP("%1 &Handbook"), 0, "contents" },
112 { WhatsThis, /*USKStdAccel::WhatsThis,*/ "help_whats_this", I18N_NOOP("What's &This?"), 0, "contexthelp" },
113 { TipofDay, /*USKStdAccel::AccelNone,*/ "help_show_tip", I18N_NOOP("Tip of the &Day"), 0, "idea" },
114 { ReportBug, /*USKStdAccel::AccelNone,*/ "help_report_bug", I18N_NOOP("&Report Bug..."), 0, 0 },
115 { AboutApp, /*USKStdAccel::AccelNone,*/ "help_about_app", I18N_NOOP("&About %1"), 0, 0 },
116 { AboutKDE, /*USKStdAccel::AccelNone,*/ "help_about_kde", I18N_NOOP("About &KDE"), 0,"about_kde" },
117 { ActionNone, /*USKStdAccel::AccelNone,*/ 0, 0, 0, 0 }
118};
119
120static const KStdActionInfo* infoPtr( StdAction id )
121{
122 for( uint i = 0; g_rgActionInfo[i].id != ActionNone; i++ ) {
123 if( g_rgActionInfo[i].id == id )
124 return &g_rgActionInfo[i];
125 }
126 return 0;
127}
128
129QStringList stdNames()
130{
131 QStringList result;
132
133 for( uint i = 0; g_rgActionInfo[i].id != ActionNone; i++ )
134 if (g_rgActionInfo[i].psLabel)
135 result.append(i18n(g_rgActionInfo[i].psLabel));
136 return result;
137}
138
139KAction* create( StdAction id, const char *name, const QObject *recvr, const char *slot, KActionCollection* parent )
140{
141 KAction* pAction = 0;
142 const KStdActionInfo* pInfo = infoPtr( id );
143 kdDebug(125) << "KStdAction::create( " << id << "=" << (pInfo ? pInfo->psName : (const char*)0) << ", " << parent << ", " << name << " )" << endl; // ellis
144 if( pInfo ) {
145 QString sLabel, iconName = pInfo->psIconName;
146 switch( id ) {
147 case Back: sLabel = i18n("go back", "&Back");
148 //US if (QApplication::reverseLayout() )
149 //US iconName = "forward";
150 break;
151
152 case Forward: sLabel = i18n("go forward", "&Forward");
153 //US if (QApplication::reverseLayout() )
154 //US iconName = "back";
155 break;
156
157 case Home: sLabel = i18n("beginning (of line)", "&Home"); break;
158 case Help: sLabel = i18n("show help", "&Help"); break;
159 //US case AboutApp: iconName = kapp->miniIconName();
160 case Preferences:
161 case HelpContents:
162 {
163 //US const KAboutData *aboutData = KGlobal::instance()->aboutData();
164 //US QString appName = (aboutData) ? aboutData->programName() : QString::fromLatin1(qApp->name());
165 QString appName = QString::fromLatin1(KGlobal::getAppName());
166 sLabel = i18n(pInfo->psLabel).arg(appName);
167 }
168 break;
169 default: sLabel = i18n(pInfo->psLabel);
170 }
171
172 /*US if (QApplication::reverseLayout()){
173 if (id == Prior) iconName = "next";
174 if (id == Next ) iconName = "previous";
175 }
176 */
177 //US KShortcut cut = KStdAccel::shortcut(pInfo->idAccel);
178 KShortcut cut;
179 switch( id ) {
180 case OpenRecent:
181 pAction = new KRecentFilesAction( sLabel, cut,
182 recvr, slot,
183 parent, (name) ? name : pInfo->psName );
184 break;
185 case ShowMenubar:
186 case ShowToolbar:
187 case ShowStatusbar:
188 KToggleAction *ret;
189 ret = new KToggleAction( sLabel, pInfo->psIconName, cut,
190 recvr, slot,
191 parent, (name) ? name : pInfo->psName );
192 ret->setChecked( true );
193 pAction = ret;
194 break;
195 default:
196 pAction = new KAction( sLabel, iconName, cut,
197 recvr, slot,
198 parent, (name) ? name : pInfo->psName );
199 break;
200 }
201 }
202 return pAction;
203}
204
205const char* name( StdAction id )
206{
207 const KStdActionInfo* pInfo = infoPtr( id );
208 return (pInfo) ? pInfo->psName : 0;
209}
210
211KAction *openNew( const QObject *recvr, const char *slot, KActionCollection* parent, const char *name )
212 { return KStdAction::create( New, name, recvr, slot, parent ); }
213KAction *open( const QObject *recvr, const char *slot, KActionCollection* parent, const char *name )
214 { return KStdAction::create( Open, name, recvr, slot, parent ); }
215KRecentFilesAction *openRecent( const QObject *recvr, const char *slot, KActionCollection* parent, const char *name )
216 { return (KRecentFilesAction*) KStdAction::create( OpenRecent, name, recvr, slot, parent ); }
217KAction *save( const QObject *recvr, const char *slot, KActionCollection* parent, const char *name )
218 { return KStdAction::create( Save, name, recvr, slot, parent ); }
219KAction *saveAs( const QObject *recvr, const char *slot, KActionCollection* parent, const char *name )
220 { return KStdAction::create( SaveAs, name, recvr, slot, parent ); }
221KAction *revert( const QObject *recvr, const char *slot, KActionCollection* parent, const char *name )
222 { return KStdAction::create( Revert, name, recvr, slot, parent ); }
223KAction *print( const QObject *recvr, const char *slot, KActionCollection* parent, const char *name )
224 { return KStdAction::create( Print, name, recvr, slot, parent ); }
225KAction *printPreview( const QObject *recvr, const char *slot, KActionCollection* parent, const char *name )
226 { return KStdAction::create( PrintPreview, name, recvr, slot, parent ); }
227KAction *close( const QObject *recvr, const char *slot, KActionCollection* parent, const char *name )
228 { return KStdAction::create( Close, name, recvr, slot, parent ); }
229KAction *mail( const QObject *recvr, const char *slot, KActionCollection* parent, const char *name )
230 { return KStdAction::create( Mail, name, recvr, slot, parent ); }
231KAction *quit( const QObject *recvr, const char *slot, KActionCollection* parent, const char *name )
232 { return KStdAction::create( Quit, name, recvr, slot, parent ); }
233KAction *undo( const QObject *recvr, const char *slot, KActionCollection* parent, const char *name )
234 { return KStdAction::create( Undo, name, recvr, slot, parent ); }
235KAction *redo( const QObject *recvr, const char *slot, KActionCollection* parent, const char *name )
236 { return KStdAction::create( Redo, name, recvr, slot, parent ); }
237KAction *cut( const QObject *recvr, const char *slot, KActionCollection* parent, const char *name )
238 { return KStdAction::create( Cut, name, recvr, slot, parent ); }
239KAction *copy( const QObject *recvr, const char *slot, KActionCollection* parent, const char *name )
240 { return KStdAction::create( Copy, name, recvr, slot, parent ); }
241KAction *paste( const QObject *recvr, const char *slot, KActionCollection* parent, const char *name )
242 { return KStdAction::create( Paste, name, recvr, slot, parent ); }
243KAction *selectAll( const QObject *recvr, const char *slot, KActionCollection* parent, const char *name )
244 { return KStdAction::create( SelectAll, name, recvr, slot, parent ); }
245KAction *deselect( const QObject *recvr, const char *slot, KActionCollection* parent, const char *name )
246 { return KStdAction::create( Deselect, name, recvr, slot, parent ); }
247KAction *find( const QObject *recvr, const char *slot, KActionCollection* parent, const char *name )
248 { return KStdAction::create( Find, name, recvr, slot, parent ); }
249KAction *findNext( const QObject *recvr, const char *slot, KActionCollection* parent, const char *name )
250 { return KStdAction::create( FindNext, name, recvr, slot, parent ); }
251KAction *findPrev( const QObject *recvr, const char *slot, KActionCollection* parent, const char *name )
252 { return KStdAction::create( FindPrev, name, recvr, slot, parent ); }
253KAction *replace( const QObject *recvr, const char *slot, KActionCollection* parent, const char *name )
254 { return KStdAction::create( Replace, name, recvr, slot, parent ); }
255KAction *actualSize( const QObject *recvr, const char *slot, KActionCollection* parent, const char *name )
256 { return KStdAction::create( ActualSize, name, recvr, slot, parent ); }
257KAction *fitToPage( const QObject *recvr, const char *slot, KActionCollection* parent, const char *name )
258 { return KStdAction::create( FitToPage, name, recvr, slot, parent ); }
259KAction *fitToWidth( const QObject *recvr, const char *slot, KActionCollection* parent, const char *name )
260 { return KStdAction::create( FitToWidth, name, recvr, slot, parent ); }
261KAction *fitToHeight( const QObject *recvr, const char *slot, KActionCollection* parent, const char *name )
262 { return KStdAction::create( FitToHeight, name, recvr, slot, parent ); }
263KAction *zoomIn( const QObject *recvr, const char *slot, KActionCollection* parent, const char *name )
264 { return KStdAction::create( ZoomIn, name, recvr, slot, parent ); }
265KAction *zoomOut( const QObject *recvr, const char *slot, KActionCollection* parent, const char *name )
266 { return KStdAction::create( ZoomOut, name, recvr, slot, parent ); }
267KAction *zoom( const QObject *recvr, const char *slot, KActionCollection* parent, const char *name )
268 { return KStdAction::create( Zoom, name, recvr, slot, parent ); }
269KAction *redisplay( const QObject *recvr, const char *slot, KActionCollection* parent, const char *name )
270 { return KStdAction::create( Redisplay, name, recvr, slot, parent ); }
271KAction *up( const QObject *recvr, const char *slot, KActionCollection* parent, const char *name )
272 { return KStdAction::create( Up, name, recvr, slot, parent ); }
273KAction *back( const QObject *recvr, const char *slot, KActionCollection* parent, const char *name )
274 { return KStdAction::create( Back, name, recvr, slot, parent ); }
275KAction *forward( const QObject *recvr, const char *slot, KActionCollection* parent, const char *name )
276 { return KStdAction::create( Forward, name, recvr, slot, parent ); }
277KAction *home( const QObject *recvr, const char *slot, KActionCollection* parent, const char *name )
278 { return KStdAction::create( Home, name, recvr, slot, parent ); }
279KAction *prior( const QObject *recvr, const char *slot, KActionCollection* parent, const char *name )
280 { return KStdAction::create( Prior, name, recvr, slot, parent ); }
281KAction *next( const QObject *recvr, const char *slot, KActionCollection* parent, const char *name )
282 { return KStdAction::create( Next, name, recvr, slot, parent ); }
283KAction *goTo( const QObject *recvr, const char *slot, KActionCollection* parent, const char *name )
284 { return KStdAction::create( Goto, name, recvr, slot, parent ); }
285KAction *gotoPage( const QObject *recvr, const char *slot, KActionCollection* parent, const char *name )
286 { return KStdAction::create( GotoPage, name, recvr, slot, parent ); }
287KAction *gotoLine( const QObject *recvr, const char *slot, KActionCollection* parent, const char *name )
288 { return KStdAction::create( GotoLine, name, recvr, slot, parent ); }
289KAction *firstPage( const QObject *recvr, const char *slot, KActionCollection* parent, const char *name )
290 { return KStdAction::create( FirstPage, name, recvr, slot, parent ); }
291KAction *lastPage( const QObject *recvr, const char *slot, KActionCollection* parent, const char *name )
292 { return KStdAction::create( LastPage, name, recvr, slot, parent ); }
293KAction *addBookmark( const QObject *recvr, const char *slot, KActionCollection* parent, const char *name )
294 { return KStdAction::create( AddBookmark, name, recvr, slot, parent ); }
295KAction *editBookmarks( const QObject *recvr, const char *slot, KActionCollection* parent, const char *name )
296 { return KStdAction::create( EditBookmarks, name, recvr, slot, parent ); }
297KAction *spelling( const QObject *recvr, const char *slot, KActionCollection* parent, const char *name )
298 { return KStdAction::create( Spelling, name, recvr, slot, parent ); }
299
300KToggleAction *showMenubar( const QObject *recvr, const char *slot, KActionCollection* parent, const char *_name )
301{
302 KToggleAction *ret;
303 ret = new KToggleAction(i18n("Show &Menubar"), "showmenu", /*US KStdAccel::shortcut(KStdAccel::ShowMenubar)*/0, recvr, slot,
304 parent, _name ? _name : name(ShowMenubar));
305 ret->setChecked(true);
306 return ret;
307}
308
309KToggleAction *showToolbar( const QObject *recvr, const char *slot, KActionCollection* parent, const char *_name )
310{
311 KToggleAction *ret;
312 ret = new KToggleAction(i18n("Show &Toolbar"), 0, recvr, slot, parent,
313 _name ? _name : name(ShowToolbar));
314 ret->setChecked(true);
315 return ret;
316
317}
318
319KToggleToolBarAction *showToolbar( const char* toolBarName, KActionCollection* parent, const char *_name )
320{
321 KToggleToolBarAction *ret;
322 ret = new KToggleToolBarAction(toolBarName, i18n("Show &Toolbar"), parent,
323 _name ? _name : name(ShowToolbar));
324 return ret;
325}
326
327KToggleAction *showStatusbar( const QObject *recvr, const char *slot,
328 KActionCollection* parent, const char *_name )
329{
330 KToggleAction *ret;
331 ret = new KToggleAction(i18n("Show St&atusbar"), 0, recvr, slot, parent,
332 _name ? _name : name(ShowStatusbar));
333 ret->setChecked(true);
334 return ret;
335}
336
337KAction *saveOptions( const QObject *recvr, const char *slot, KActionCollection* parent, const char *name )
338 { return KStdAction::create( SaveOptions, name, recvr, slot, parent ); }
339KAction *keyBindings( const QObject *recvr, const char *slot, KActionCollection* parent, const char *name )
340 { return KStdAction::create( KeyBindings, name, recvr, slot, parent ); }
341KAction *preferences( const QObject *recvr, const char *slot, KActionCollection* parent, const char *name )
342 { return KStdAction::create( Preferences, name, recvr, slot, parent ); }
343KAction *configureToolbars( const QObject *recvr, const char *slot, KActionCollection* parent, const char *name )
344 { return KStdAction::create( ConfigureToolbars, name, recvr, slot, parent ); }
345KAction *configureNotifications( const QObject *recvr, const char *slot, KActionCollection* parent, const char *name )
346 { return KStdAction::create( ConfigureNotifications, name, recvr, slot, parent ); }
347KAction *help( const QObject *recvr, const char *slot, KActionCollection* parent, const char *name )
348 { return KStdAction::create( Help, name, recvr, slot, parent ); }
349KAction *helpContents( const QObject *recvr, const char *slot, KActionCollection* parent, const char *name )
350 { return KStdAction::create( HelpContents, name, recvr, slot, parent ); }
351KAction *whatsThis( const QObject *recvr, const char *slot, KActionCollection* parent, const char *name )
352 { return KStdAction::create( WhatsThis, name, recvr, slot, parent ); }
353KAction *tipOfDay( const QObject *recvr, const char *slot, KActionCollection* parent, const char *name )
354 { return KStdAction::create( TipofDay, name, recvr, slot, parent ); }
355KAction *reportBug( const QObject *recvr, const char *slot, KActionCollection* parent, const char *name )
356 { return KStdAction::create( ReportBug, name, recvr, slot, parent ); }
357KAction *aboutApp( const QObject *recvr, const char *slot, KActionCollection* parent, const char *name )
358 { return KStdAction::create( AboutApp, name, recvr, slot, parent ); }
359KAction *aboutKDE( const QObject *recvr, const char *slot, KActionCollection* parent, const char *name )
360 { return KStdAction::create( AboutKDE, name, recvr, slot, parent ); }
361
362}
diff --git a/microkde/kdeui/kstdaction.h b/microkde/kdeui/kstdaction.h
new file mode 100644
index 0000000..bc712b3
--- a/dev/null
+++ b/microkde/kdeui/kstdaction.h
@@ -0,0 +1,568 @@
1/* This file is part of the KDE libraries
2 Copyright (C) 1999,2000 Kurt Granroth <granroth@kde.org>
3 Copyright (C) 2001,2002 Ellis Whitehead <ellis@kde.org>
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License version 2 as published by the Free Software Foundation.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA.
18*/
19#ifndef KSTDACTION_H
20#define KSTDACTION_H
21
22class QObject;
23class KAction;
24class KActionCollection;
25class KRecentFilesAction;
26class KToggleAction;
27class KToggleToolBarAction;
28
29#include <qstringlist.h>
30
31/**
32 * Convenience methods to access all standard KDE actions.
33 *
34 * These actions should be used instead of hardcoding menubar and
35 * toolbar items. Using these actions helps your application easily
36 * conform to the KDE UI Style Guide
37 * @see http://developer.kde.org/documentation/standards/kde/style/basics/index.html .
38 *
39 * All of the documentation for @ref KAction holds for KStdAction
40 * also. When in doubt on how things work, check the @ref KAction
41 * documention first.
42 *
43 * @sect Simple Example:
44 *
45 * In general, using standard actions should be a drop in replacement
46 * for regular actions. For example, if you previously had:
47 *
48 * <PRE>
49 * KAction *newAct = new KAction(i18n("&New"), QIconSet(BarIcon("filenew")),
50 * KStdAccel::key(KStdAccel::New), this,
51 * SLOT(fileNew()), actionCollection());
52 * </PRE>
53 *
54 * You could drop that and replace it with:
55 *
56 * <PRE>
57 * KAction *newAct = KStdAction::openNew(this, SLOT(fileNew()),
58 * actionCollection());
59 * </PRE>
60 *
61 * @sect Non-standard Usages
62 *
63 * It is possible to use the standard actions in various
64 * non-recommended ways. Say, for instance, you wanted to have a
65 * standard action (with the associated correct text and icon and
66 * accelerator, etc) but you didn't want it to go in the standard
67 * place (this is not recommended, by the way). One way to do this is
68 * to simply not use the XML UI framework and plug it into wherever
69 * you want. If you do want to use the XML UI framework (good!), then
70 * it is still possible.
71 *
72 * Basically, the XML building code matches names in the XML code with
73 * the internal names of the actions. You can find out the internal
74 * names of each of the standard actions by using the @ref stdName
75 * action like so: @ref KStdAction::stdName(KStdAction::Cut) would return
76 * 'edit_cut'. The XML building code will match 'edit_cut' to the
77 * attribute in the global XML file and place your action there.
78 *
79 * However, you can change the internal name. In this example, just
80 * do something like:
81 *
82 * <PRE>
83 * (void)KStdAction::cut(this, SLOT(editCut()), actionCollection(), "my_cut");
84 * </PRE>
85 *
86 * Now, in your local XML resource file (e.g., yourappui.rc), simply
87 * put 'my_cut' where you want it to go.
88 *
89 * Another non-standard usage concerns getting a pointer to an
90 * existing action if, say, you want to enable or disable the action.
91 * You could do it the recommended way and just grab a pointer when
92 * you instantiate it as in the the 'openNew' example above... or you
93 * could do it the hard way:
94 *
95 * <pre>
96 * KAction *cut = actionCollection()->action(KStdAction::stdName(KStdAction::Cut));
97 * </pre>
98 *
99 * Another non-standard usage concerns instantiating the action in the
100 * first place. Usually, you would use the member functions as
101 * shown above (e.g., KStdAction::cut(this, SLOT, parent)). You
102 * may, however, do this using the enums provided. This author can't
103 * think of a reason why you would want to, but, hey, if you do,
104 * here's how:
105 *
106 * <pre>
107 * (void)KStdAction::action(KStdAction::New, this, SLOT(fileNew()), actionCollection());
108 * (void)KStdAction::action(KStdAction::Cut, this, SLOT(editCut()), actionCollection());
109 * </pre>
110 *
111 * @author Kurt Granroth <granroth@kde.org>
112 */
113namespace KStdAction
114{
115 /**
116 * The standard menubar and toolbar actions.
117 */
118 enum StdAction {
119 ActionNone,
120
121 // File Menu
122 New, Open, OpenRecent, Save, SaveAs, Revert, Close,
123 Print, PrintPreview, Mail, Quit,
124
125 // Edit Menu
126 Undo, Redo, Cut, Copy, Paste, SelectAll, Deselect, Find, FindNext, FindPrev,
127 Replace,
128
129 // View Menu
130 ActualSize, FitToPage, FitToWidth, FitToHeight, ZoomIn, ZoomOut,
131 Zoom, Redisplay,
132
133 // Go Menu
134 Up, Back, Forward, Home, Prior, Next, Goto, GotoPage, GotoLine,
135 FirstPage, LastPage,
136
137 // Bookmarks Menu
138 AddBookmark, EditBookmarks,
139
140 // Tools Menu
141 Spelling,
142
143 // Settings Menu
144 ShowMenubar, ShowToolbar, ShowStatusbar, SaveOptions, KeyBindings,
145 Preferences, ConfigureToolbars,
146
147 // Help Menu
148 Help, HelpContents, WhatsThis, ReportBug, AboutApp, AboutKDE,
149 TipofDay, ///< @since 3.1
150
151 // Another settings menu item
152 ConfigureNotifications
153 };
154
155 /**
156 * Creates an action corresponding to the
157 * @ref KStdAction::StdAction enum.
158 */
159 KAction* create( StdAction id, const char *name,
160 const QObject *recvr, const char *slot,
161 KActionCollection* parent );
162
163 inline KAction* create( StdAction id,
164 const QObject *recvr, const char *slot,
165 KActionCollection* parent )
166 { return KStdAction::create( id, 0, recvr, slot, parent ); }
167
168 /**
169 * @obsolete. Creates an action corresponding to the
170 * @ref KStdAction::StdAction enum.
171 */
172 inline KAction *action(StdAction act_enum,
173 const QObject *recvr, const char *slot,
174 KActionCollection *parent, const char *name = 0L )
175 { return KStdAction::create( act_enum, name, recvr, slot, parent ); }
176
177 /**
178 * This will return the internal name of a given standard action.
179 */
180 const char* name( StdAction id );
181
182 /// @obsolete. Use #name
183 inline const char* stdName(StdAction act_enum) { return name( act_enum ); }
184
185 /**
186 * Returns a list of all standard names. Used by @ref KAccelManager
187 * to give those heigher weight.
188 * @since 3.1
189 */
190 QStringList stdNames();
191
192 /**
193 * Create a new document or window.
194 */
195 KAction *openNew(const QObject *recvr, const char *slot, KActionCollection* parent, const char *name = 0 );
196
197 /**
198 * Open an existing file.
199 */
200 KAction *open(const QObject *recvr, const char *slot, KActionCollection* parent, const char *name = 0 );
201
202 /**
203 * Open a recently used document.
204 * @param slot The SLOT to invoke when a URL is selected.
205 * Its signature is of the form slotURLSelected( const KURL & ).
206 */
207 KRecentFilesAction *openRecent(const QObject *recvr, const char *slot, KActionCollection* parent, const char *name = 0 );
208
209 /**
210 * Save the current document.
211 */
212 KAction *save(const QObject *recvr, const char *slot,
213 KActionCollection* parent, const char *name = 0 );
214
215 /**
216 * Save the current document under a different name.
217 */
218 KAction *saveAs(const QObject *recvr, const char *slot,
219 KActionCollection* parent, const char *name = 0 );
220
221 /**
222 * Revert the current document to the last saved version
223 * (essentially will undo all changes).
224 */
225 KAction *revert(const QObject *recvr, const char *slot,
226 KActionCollection* parent, const char *name = 0 );
227
228 /**
229 * Close the current document.
230 */
231 KAction *close(const QObject *recvr, const char *slot,
232 KActionCollection* parent, const char *name = 0 );
233
234 /**
235 * Print the current document.
236 */
237 KAction *print(const QObject *recvr, const char *slot,
238 KActionCollection* parent, const char *name = 0 );
239
240 /**
241 * Show a print preview of the current document.
242 */
243 KAction *printPreview(const QObject *recvr, const char *slot,
244 KActionCollection* parent, const char *name = 0 );
245
246 /**
247 * Mail this document.
248 */
249 KAction *mail(const QObject *recvr, const char *slot,
250 KActionCollection* parent, const char *name = 0 );
251
252 /**
253 * Quit the program.
254 */
255 KAction *quit(const QObject *recvr, const char *slot,
256 KActionCollection* parent, const char *name = 0 );
257
258 /**
259 * Undo the last operation.
260 */
261 KAction *undo(const QObject *recvr, const char *slot,
262 KActionCollection* parent, const char *name = 0 );
263
264 /**
265 * Redo the last operation.
266 */
267 KAction *redo(const QObject *recvr, const char *slot,
268 KActionCollection* parent, const char *name = 0 );
269
270 /**
271 * Cut selected area and store it in the clipboard.
272 */
273 KAction *cut(const QObject *recvr, const char *slot,
274 KActionCollection* parent, const char *name = 0 );
275
276 /**
277 * Copy the selected area into the clipboard.
278 */
279 KAction *copy(const QObject *recvr, const char *slot,
280 KActionCollection* parent, const char *name = 0 );
281
282 /**
283 * Paste the contents of clipboard at the current mouse or cursor
284 * position.
285 */
286 KAction *paste(const QObject *recvr, const char *slot,
287 KActionCollection* parent, const char *name = 0 );
288
289 /**
290 * Select all elements in the current document.
291 */
292 KAction *selectAll(const QObject *recvr, const char *slot,
293 KActionCollection* parent, const char *name = 0 );
294
295 /**
296 * Deselect any selected elements in the current document.
297 */
298 KAction *deselect(const QObject *recvr, const char *slot,
299 KActionCollection* parent, const char *name = 0 );
300
301 /**
302 * Initiate a 'find' request in the current document.
303 */
304 KAction *find(const QObject *recvr, const char *slot,
305 KActionCollection* parent, const char *name = 0 );
306
307 /**
308 * Find the next instance of a stored 'find'.
309 */
310 KAction *findNext(const QObject *recvr, const char *slot,
311 KActionCollection* parent, const char *name = 0 );
312
313 /**
314 * Find a previous instance of a stored 'find'.
315 */
316 KAction *findPrev(const QObject *recvr, const char *slot,
317 KActionCollection* parent, const char *name = 0 );
318
319 /**
320 * Find and replace matches.
321 */
322 KAction *replace(const QObject *recvr, const char *slot,
323 KActionCollection* parent, const char *name = 0 );
324
325 /**
326 * View the document at its actual size.
327 */
328 KAction *actualSize(const QObject *recvr, const char *slot,
329 KActionCollection* parent, const char *name = 0 );
330
331 /**
332 * Fit the document view to the size of the current window.
333 */
334 KAction *fitToPage(const QObject *recvr, const char *slot,
335 KActionCollection* parent, const char *name = 0 );
336
337 /**
338 * Fit the document view to the width of the current window.
339 */
340 KAction *fitToWidth(const QObject *recvr, const char *slot,
341 KActionCollection* parent, const char *name = 0 );
342
343 /**
344 * Fit the document view to the height of the current window.
345 */
346 KAction *fitToHeight(const QObject *recvr, const char *slot,
347 KActionCollection* parent, const char *name = 0 );
348
349 /**
350 * Zoom in.
351 */
352 KAction *zoomIn(const QObject *recvr, const char *slot,
353 KActionCollection* parent, const char *name = 0 );
354
355 /**
356 * Zoom out.
357 */
358 KAction *zoomOut(const QObject *recvr, const char *slot,
359 KActionCollection* parent, const char *name = 0 );
360
361 /**
362 * Popup a zoom dialog.
363 */
364 KAction *zoom(const QObject *recvr, const char *slot,
365 KActionCollection* parent, const char *name = 0 );
366
367 /**
368 * Redisplay or redraw the document.
369 */
370 KAction *redisplay(const QObject *recvr, const char *slot,
371 KActionCollection* parent, const char *name = 0 );
372
373 /**
374 * Move up (web style menu).
375 */
376 KAction *up(const QObject *recvr, const char *slot,
377 KActionCollection* parent, const char *name = 0 );
378
379 /**
380 * Move back (web style menu).
381 */
382 KAction *back(const QObject *recvr, const char *slot,
383 KActionCollection* parent, const char *name = 0 );
384
385 /**
386 * Move forward (web style menu).
387 */
388 KAction *forward(const QObject *recvr, const char *slot,
389 KActionCollection* parent, const char *name = 0 );
390
391 /**
392 * Go to the "Home" position or document.
393 */
394 KAction *home(const QObject *recvr, const char *slot,
395 KActionCollection* parent, const char *name = 0 );
396
397 /**
398 * Scroll up one page.
399 */
400 KAction *prior(const QObject *recvr, const char *slot,
401 KActionCollection* parent, const char *name = 0 );
402
403 /**
404 * Scroll down one page.
405 */
406 KAction *next(const QObject *recvr, const char *slot,
407 KActionCollection* parent, const char *name = 0 );
408
409 /**
410 * Go to somewhere in general.
411 */
412 KAction *goTo(const QObject *recvr, const char *slot,
413 KActionCollection* parent, const char *name = 0 );
414
415
416 /**
417 * Go to a specific page (dialog).
418 */
419 KAction *gotoPage(const QObject *recvr, const char *slot,
420 KActionCollection* parent, const char *name = 0 );
421
422 /**
423 * Go to a specific line (dialog).
424 */
425 KAction *gotoLine(const QObject *recvr, const char *slot,
426 KActionCollection* parent, const char *name = 0 );
427
428 /**
429 * Jump to the first page.
430 */
431 KAction *firstPage(const QObject *recvr, const char *slot,
432 KActionCollection* parent, const char *name = 0 );
433
434 /**
435 * Jump to the last page.
436 */
437 KAction *lastPage(const QObject *recvr, const char *slot,
438 KActionCollection* parent, const char *name = 0 );
439
440 /**
441 * Add the current page to the bookmarks tree.
442 */
443 KAction *addBookmark(const QObject *recvr, const char *slot,
444 KActionCollection* parent, const char *name = 0 );
445
446 /**
447 * Edit the application bookmarks.
448 */
449 KAction *editBookmarks(const QObject *recvr, const char *slot,
450 KActionCollection* parent, const char *name = 0 );
451
452 /**
453 * Pop up the spell checker.
454 */
455 KAction *spelling(const QObject *recvr, const char *slot,
456 KActionCollection* parent, const char *name = 0 );
457
458
459 /**
460 * Show/Hide the menubar.
461 */
462 KToggleAction *showMenubar(const QObject *recvr, const char *slot,
463 KActionCollection* parent, const char *name = 0 );
464
465 /**
466 * @obsolete. toolbar actions are created automatically now in the
467 * Settings menu. Don't use this anymore.
468 * See: @ref KMainWindow::createStandardStatusBarAction()
469 * Show/Hide the primary toolbar.
470 * @since 3.1
471 */
472 KToggleAction *showToolbar(const QObject *recvr, const char *slot,
473 KActionCollection* parent, const char *name = 0 );
474 /**
475 * @obsolete. toolbar actions are created automatically now in the
476 * Settings menu. Don't use this anymore.
477 * See: @ref KMainWindow::setStandardToolBarMenuEnabled(bool);
478 * Show/Hide the primary toolbar.
479 */
480 KToggleToolBarAction *showToolbar(const char* toolBarName,
481 KActionCollection* parent, const char *name = 0 );
482
483 /**
484 * Show/Hide the statusbar.
485 */
486 KToggleAction *showStatusbar(const QObject *recvr, const char *slot,
487 KActionCollection* parent, const char *name = 0 );
488
489 /**
490 * Display the save options dialog.
491 */
492 KAction *saveOptions(const QObject *recvr, const char *slot,
493 KActionCollection* parent, const char *name = 0 );
494
495 /**
496 * Display the configure key bindings dialog.
497 */
498 KAction *keyBindings(const QObject *recvr, const char *slot,
499 KActionCollection* parent, const char *name = 0 );
500
501 /**
502 * Display the preferences/options dialog.
503 */
504 KAction *preferences(const QObject *recvr, const char *slot,
505 KActionCollection* parent, const char *name = 0 );
506
507 /**
508 * The Customize Toolbar dialog.
509 */
510 KAction *configureToolbars(const QObject *recvr,
511 const char *slot,
512 KActionCollection* parent,
513 const char *name = 0 );
514
515 /**
516 * The Configure Notifications dialo
517 * @since 3.1
518 */
519 KAction *configureNotifications(const QObject *recvr,
520 const char *slot,
521 KActionCollection *parent,
522 const char *name = 0);
523
524 /**
525 * Display the help.
526 */
527 KAction *help(const QObject *recvr, const char *slot,
528 KActionCollection* parent, const char *name = 0 );
529
530 /**
531 * Display the help contents.
532 */
533 KAction *helpContents(const QObject *recvr, const char *slot,
534 KActionCollection* parent, const char *name = 0 );
535
536 /**
537 * Trigger the What's This cursor.
538 */
539 KAction *whatsThis(const QObject *recvr, const char *slot,
540 KActionCollection* parent, const char *name = 0 );
541
542 /**
543 * Display "Tip of the Day"
544 * @since 3.1
545 */
546 KAction *tipOfDay(const QObject *recvr, const char *slot,
547 KActionCollection* parent, const char *name = 0 );
548
549 /**
550 * Open up the Report Bug dialog.
551 */
552 KAction *reportBug(const QObject *recvr, const char *slot,
553 KActionCollection* parent, const char *name = 0 );
554
555 /**
556 * Display the application's About box.
557 */
558 KAction *aboutApp(const QObject *recvr, const char *slot,
559 KActionCollection* parent, const char *name = 0 );
560
561 /**
562 * Display the About KDE dialog.
563 */
564 KAction *aboutKDE(const QObject *recvr, const char *slot,
565 KActionCollection* parent, const char *name = 0 );
566}
567
568#endif // KSTDACTION_H
diff --git a/microkde/kdeui/ktoolbar.cpp b/microkde/kdeui/ktoolbar.cpp
new file mode 100644
index 0000000..92cb8d2
--- a/dev/null
+++ b/microkde/kdeui/ktoolbar.cpp
@@ -0,0 +1,2260 @@
1/* This file is part of the KDE libraries
2 Copyright
3 (C) 2000 Reginald Stadlbauer (reggie@kde.org)
4 (C) 1997, 1998 Stephan Kulow (coolo@kde.org)
5 (C) 1997, 1998 Mark Donohoe (donohoe@kde.org)
6 (C) 1997, 1998 Sven Radej (radej@kde.org)
7 (C) 1997, 1998 Matthias Ettrich (ettrich@kde.org)
8 (C) 1999 Chris Schlaeger (cs@kde.org)
9 (C) 1999 Kurt Granroth (granroth@kde.org)
10
11 This library is free software; you can redistribute it and/or
12 modify it under the terms of the GNU Library General Public
13 License version 2 as published by the Free Software Foundation.
14
15 This library is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 Library General Public License for more details.
19
20 You should have received a copy of the GNU Library General Public License
21 along with this library; see the file COPYING.LIB. If not, write to
22 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23 Boston, MA 02111-1307, USA.
24*/
25
26#ifdef KDE_USE_FINAL
27#undef Always
28#include <qdockwindow.h>
29#endif
30
31
32
33#include "ktoolbar.h"
34#include "kmainwindow.h"
35
36#include <string.h>
37
38#include <qpainter.h>
39#include <qtooltip.h>
40#include <qdrawutil.h>
41#include <qstring.h>
42#include <qrect.h>
43#include <qobjectlist.h>
44#include <qtimer.h>
45#include <qstyle.h>
46#include <qapplication.h>
47
48//US #include <config.h>
49
50#include "klineedit.h"
51#include "kseparator.h"
52#include <klocale.h>
53#include <kapplication.h>
54#include <kaction.h>
55#include <kstdaction.h>
56#include <kglobal.h>
57#include <kconfig.h>
58#include <kiconloader.h>
59#include <kcombobox.h>
60//US #include <kpopupmenu.h>
61//US #include <kanimwidget.h>
62//US #include <kipc.h>
63//US #include <kwin.h>
64#include <kdebug.h>
65#include <qlayout.h>
66
67#include "ktoolbarbutton.h"
68
69//US
70#include "kconfigbase.h"
71
72#include <qpopupmenu.h>
73#include <qmainwindow.h>
74
75enum {
76 CONTEXT_TOP = 0,
77 CONTEXT_LEFT = 1,
78 CONTEXT_RIGHT = 2,
79 CONTEXT_BOTTOM = 3,
80 CONTEXT_FLOAT = 4,
81 CONTEXT_FLAT = 5,
82 CONTEXT_ICONS = 6,
83 CONTEXT_TEXT = 7,
84 CONTEXT_TEXTRIGHT = 8,
85 CONTEXT_TEXTUNDER = 9,
86 CONTEXT_ICONSIZES = 50 // starting point for the icon size list, put everything else before
87};
88
89class KToolBarPrivate
90{
91public:
92 KToolBarPrivate() {
93 m_iconSize = 0;
94 m_iconText = KToolBar::IconOnly;
95 m_highlight = true;
96 m_transparent = true;
97 m_honorStyle = false;
98
99 m_enableContext = true;
100
101 m_xmlguiClient = 0;
102 m_configurePlugged = false;
103
104//US oldPos = Qt::DockUnmanaged;
105 oldPos = QMainWindow::Unmanaged;
106
107 modified = m_isHorizontal = positioned = FALSE;
108
109 HiddenDefault = false;
110 IconSizeDefault = 0;
111 IconTextDefault = "IconOnly";
112 IndexDefault = -1;
113 NewLineDefault = false;
114 OffsetDefault = -1;
115 PositionDefault = "Top";
116 idleButtons.setAutoDelete(true);
117 }
118
119 int m_iconSize;
120 KToolBar::IconText m_iconText;
121 bool m_highlight : 1;
122 bool m_transparent : 1;
123 bool m_honorStyle : 1;
124 bool m_isHorizontal : 1;
125 bool m_enableContext : 1;
126 bool m_configurePlugged : 1;
127 bool modified : 1;
128 bool positioned : 1;
129
130 QWidget *m_parent;
131
132 QMainWindow::ToolBarDock oldPos;
133
134 KXMLGUIClient *m_xmlguiClient;
135
136 struct ToolBarInfo
137 {
138//US ToolBarInfo() : index( 0 ), offset( -1 ), newline( FALSE ), dock( Qt::DockTop ) {}
139 ToolBarInfo() : index( 0 ), offset( -1 ), newline( FALSE ), dock( QMainWindow::Top ) {}
140//US ToolBarInfo( Qt::Dock d, int i, bool n, int o ) : index( i ), offset( o ), newline( n ), dock( d ) {}
141 ToolBarInfo( QMainWindow::ToolBarDock d, int i, bool n, int o ) : index( i ), offset( o ), newline( n ), dock( d ) {}
142 int index, offset;
143 bool newline;
144//US Qt::Dock dock;
145 QMainWindow::ToolBarDock dock;
146 };
147
148 ToolBarInfo toolBarInfo;
149 QValueList<int> iconSizes;
150 QTimer repaintTimer;
151
152 // Default Values.
153 bool HiddenDefault;
154 int IconSizeDefault;
155 QString IconTextDefault;
156 int IndexDefault;
157 bool NewLineDefault;
158 int OffsetDefault;
159 QString PositionDefault;
160
161 QPtrList<QWidget> idleButtons;
162};
163
164KToolBarSeparator::KToolBarSeparator(Orientation o , bool l, QToolBar *parent,
165 const char* name )
166 :QFrame( parent, name ), line( l )
167{
168 connect( parent, SIGNAL(orientationChanged(Orientation)),
169 this, SLOT(setOrientation(Orientation)) );
170 setOrientation( o );
171 setBackgroundMode( parent->backgroundMode() );
172 setBackgroundOrigin( ParentOrigin );
173}
174
175void KToolBarSeparator::setOrientation( Orientation o )
176{
177 orient = o;
178 if ( line ) {
179 if ( orientation() == Vertical )
180 setFrameStyle( HLine + Sunken );
181 else
182 setFrameStyle( VLine + Sunken );
183 } else {
184 setFrameStyle( NoFrame );
185 }
186}
187
188void KToolBarSeparator::styleChange( QStyle& )
189{
190 setOrientation( orient );
191}
192
193QSize KToolBarSeparator::sizeHint() const
194{
195 return orientation() == Vertical ? QSize( 0, 6 ) : QSize( 6, 0 );
196}
197
198QSizePolicy KToolBarSeparator::sizePolicy() const
199{
200 return QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum );
201}
202
203KToolBar::KToolBar( QWidget *parent, const char *name, bool honorStyle, bool readConfig )
204#ifdef DESKTOP_VERSION
205 : QToolBar( QString::fromLatin1( name ),
206 parent && parent->inherits( "QMainWindow" ) ? static_cast<QMainWindow*>(parent) : 0,
207 parent, FALSE,
208 name ? name : "mainToolBar")
209#else
210 : QPEToolBar( parent && parent->inherits( "QMainWindow" ) ? static_cast<QMainWindow*>(parent) : 0,
211 QString::fromLatin1( name ))
212
213
214#endif
215{
216 init( readConfig, honorStyle );
217}
218
219KToolBar::KToolBar( QMainWindow *parentWindow, QMainWindow::ToolBarDock dock, bool newLine, const char *name, bool honorStyle, bool readConfig )
220#ifdef DESKTOP_VERSION
221 : QToolBar( QString::fromLatin1( name ),
222 parentWindow, dock, newLine,
223 name ? name : "mainToolBar")
224#else
225 : QPEToolBar( parentWindow,QString::fromLatin1( name ))
226
227
228#endif
229
230{
231 init( readConfig, honorStyle );
232}
233
234KToolBar::KToolBar( QMainWindow *parentWindow, QWidget *dock, bool newLine, const char *name, bool honorStyle, bool readConfig )
235#ifdef DESKTOP_VERSION
236 : QToolBar( QString::fromLatin1( name ),
237 parentWindow, dock, newLine,
238 name ? name : "mainToolBar")
239#else
240 : QPEToolBar( parentWindow,QString::fromLatin1( name ))
241
242
243#endif
244
245{
246 init( readConfig, honorStyle );
247}
248
249KToolBar::~KToolBar()
250{
251 inshutdownprocess = true;
252 emit toolbarDestroyed();
253 delete d;
254}
255
256void KToolBar::init( bool readConfig, bool honorStyle )
257{
258 inshutdownprocess = false;
259 d = new KToolBarPrivate;
260 setFullSize( TRUE );
261 d->m_honorStyle = honorStyle;
262 context = 0;
263 layoutTimer = new QTimer( this );
264 connect( layoutTimer, SIGNAL( timeout() ),
265 this, SLOT( rebuildLayout() ) );
266 connect( &(d->repaintTimer), SIGNAL( timeout() ),
267 this, SLOT( slotRepaint() ) );
268/*US
269 if ( kapp ) { // may be null when started inside designer
270 connect(kapp, SIGNAL(toolbarAppearanceChanged(int)), this, SLOT(slotAppearanceChanged()));
271 // request notification of changes in icon style
272 kapp->addKipcEventMask(KIPC::IconChanged);
273 connect(kapp, SIGNAL(iconChanged(int)), this, SLOT(slotIconChanged(int)));
274 }
275*/
276 // finally, read in our configurable settings
277 if ( readConfig )
278 slotReadConfig();
279
280 if ( mainWindow() )
281 connect( mainWindow(), SIGNAL( toolBarPositionChanged( QToolBar * ) ),
282 this, SLOT( toolBarPosChanged( QToolBar * ) ) );
283
284 // Hack to make sure we recalculate our size when we dock.
285//US connect( this, SIGNAL(placeChanged(QDockWindow::Place)), SLOT(rebuildLayout()) );
286}
287
288int KToolBar::insertButton(const QString& icon, int id, bool enabled,
289 const QString& text, int index/*US, KInstance *_instance*/ )
290{
291 KToolBarButton *button = new KToolBarButton( icon, id, this, 0, text/*US, _instance*/ );
292
293 insertWidgetInternal( button, index, id );
294 button->setEnabled( enabled );
295 doConnections( button );
296 return index;
297}
298
299
300int KToolBar::insertButton(const QString& icon, int id, const char *signal,
301 const QObject *receiver, const char *slot,
302 bool enabled, const QString& text, int index/*US, KInstance *_instance*/ )
303{
304 KToolBarButton *button = new KToolBarButton( icon, id, this, 0, text/*US, _instance*/);
305 insertWidgetInternal( button, index, id );
306 button->setEnabled( enabled );
307 connect( button, signal, receiver, slot );
308 doConnections( button );
309 return index;
310}
311
312
313int KToolBar::insertButton(const QPixmap& pixmap, int id, bool enabled,
314 const QString& text, int index )
315{
316 KToolBarButton *button = new KToolBarButton( pixmap, id, this, 0, text);
317 insertWidgetInternal( button, index, id );
318 button->setEnabled( enabled );
319 doConnections( button );
320 return index;
321}
322#if 0
323 bar->insertButton( icon, id_, SIGNAL( clicked() ), this,
324 SLOT( slotActivated() ),
325 d->isEnabled(), d->plainText(), index/*US, instance*/ );
326#endif
327
328int KToolBar::insertButton(const QPixmap& pixmap, int id, const char *signal,
329 const QObject *receiver, const char *slot,
330 bool enabled, const QString& text,
331 int index )
332{
333 KToolBarButton *button = new KToolBarButton( pixmap, id, this, 0, text);
334 insertWidgetInternal( button, index, id );
335 button->setEnabled( enabled );
336 connect( button, signal, receiver, slot );
337 doConnections( button );
338 return index;
339}
340
341
342int KToolBar::insertButton(const QString& icon, int id, QPopupMenu *popup,
343 bool enabled, const QString &text, int index )
344{
345 KToolBarButton *button = new KToolBarButton( icon, id, this, 0, text );
346 insertWidgetInternal( button, index, id );
347 button->setEnabled( enabled );
348 button->setPopup( popup );
349 doConnections( button );
350 return index;
351}
352
353
354int KToolBar::insertButton(const QPixmap& pixmap, int id, QPopupMenu *popup,
355 bool enabled, const QString &text, int index )
356{
357 KToolBarButton *button = new KToolBarButton( pixmap, id, this, 0, text );
358 insertWidgetInternal( button, index, id );
359 button->setEnabled( enabled );
360 button->setPopup( popup );
361 doConnections( button );
362 return index;
363}
364
365
366int KToolBar::insertLined (const QString& text, int id,
367 const char *signal,
368 const QObject *receiver, const char *slot,
369 bool enabled ,
370 const QString& toolTipText,
371 int size, int index )
372{
373 KLineEdit *lined = new KLineEdit ( this, 0 );
374 if ( !toolTipText.isEmpty() )
375 QToolTip::add( lined, toolTipText );
376 if ( size > 0 )
377 lined->setMinimumWidth( size );
378 insertWidgetInternal( lined, index, id );
379 connect( lined, signal, receiver, slot );
380 lined->setText(text);
381 lined->setEnabled( enabled );
382 return index;
383}
384
385int KToolBar::insertCombo (const QStringList &list, int id, bool writable,
386 const char *signal, const QObject *receiver,
387 const char *slot, bool enabled,
388 const QString& tooltiptext,
389 int size, int index,
390 QComboBox::Policy policy )
391{
392//US KComboBox *combo = new KComboBox ( writable, this );
393 KComboBox *combo = new KComboBox ( this );
394 combo->setEditable(writable);
395
396 insertWidgetInternal( combo, index, id );
397 combo->insertStringList (list);
398 combo->setInsertionPolicy(policy);
399 combo->setEnabled( enabled );
400 if ( !tooltiptext.isEmpty() )
401 QToolTip::add( combo, tooltiptext );
402 if ( size > 0 )
403 combo->setMinimumWidth( size );
404 if (!tooltiptext.isNull())
405 QToolTip::add( combo, tooltiptext );
406
407 if ( signal && receiver && slot )
408 connect ( combo, signal, receiver, slot );
409 return index;
410}
411
412
413int KToolBar::insertCombo (const QString& text, int id, bool writable,
414 const char *signal, QObject *receiver,
415 const char *slot, bool enabled,
416 const QString& tooltiptext,
417 int size, int index,
418 QComboBox::Policy policy )
419{
420//US KComboBox *combo = new KComboBox ( writable, this );
421 KComboBox *combo = new KComboBox ( this );
422 combo->setEditable(writable);
423
424 insertWidgetInternal( combo, index, id );
425 combo->insertItem (text);
426 combo->setInsertionPolicy(policy);
427 combo->setEnabled( enabled );
428 if ( !tooltiptext.isEmpty() )
429 QToolTip::add( combo, tooltiptext );
430 if ( size > 0 )
431 combo->setMinimumWidth( size );
432 if (!tooltiptext.isNull())
433 QToolTip::add( combo, tooltiptext );
434 connect (combo, signal, receiver, slot);
435 return index;
436}
437
438int KToolBar::insertSeparator(int index, int id)
439{
440 QWidget *w = new KToolBarSeparator( orientation(), FALSE, this, "tool bar separator" );
441 insertWidgetInternal( w, index, id );
442 return index;
443}
444
445int KToolBar::insertLineSeparator(int index, int id)
446{
447 QWidget *w = new KToolBarSeparator( orientation(), TRUE, this, "tool bar separator" );
448 insertWidgetInternal( w, index, id );
449 return index;
450}
451
452
453int KToolBar::insertWidget(int id, int /*width*/, QWidget *widget, int index)
454{
455 // removeWidgetInternal( widget ); // in case we already have it ?
456 insertWidgetInternal( widget, index, id );
457 return index;
458}
459/*US
460int KToolBar::insertAnimatedWidget(int id, QObject *receiver, const char *slot,
461 const QString& icons, int index )
462{
463 KAnimWidget *anim = new KAnimWidget( icons, d->m_iconSize, this );
464 insertWidgetInternal( anim, index, id );
465
466 if ( receiver )
467 connect( anim, SIGNAL(clicked()), receiver, slot);
468
469 return index;
470}
471
472KAnimWidget *KToolBar::animatedWidget( int id )
473{
474 Id2WidgetMap::Iterator it = id2widget.find( id );
475 if ( it == id2widget.end() )
476 return 0;
477 if ( (*it) && (*it)->inherits( "KAnimWidget" ) )
478 return (KAnimWidget*)(*it);
479 QObjectList *l = queryList( "KAnimWidget" );
480 if ( !l || !l->first() ) {
481 delete l;
482 return 0;
483 }
484
485 for ( QObject *o = l->first(); o; o = l->next() ) {
486 if ( o->inherits( "KAnimWidget" ) )
487 {
488 delete l;
489 return (KAnimWidget*)o;
490 }
491 }
492
493 delete l;
494 return 0;
495}
496*/
497
498void KToolBar::addConnection (int id, const char *signal,
499 const QObject *receiver, const char *slot)
500{
501 Id2WidgetMap::Iterator it = id2widget.find( id );
502 if ( it == id2widget.end() )
503 return;
504 if ( (*it) )
505 connect( (*it), signal, receiver, slot );
506}
507
508void KToolBar::setItemEnabled( int id, bool enabled )
509{
510 Id2WidgetMap::Iterator it = id2widget.find( id );
511 if ( it == id2widget.end() )
512 return;
513 if ( (*it) )
514 (*it)->setEnabled( enabled );
515}
516
517
518void KToolBar::setButtonPixmap( int id, const QPixmap& _pixmap )
519{
520 Id2WidgetMap::Iterator it = id2widget.find( id );
521 if ( it == id2widget.end() )
522 return;
523//US KToolBarButton * button = dynamic_cast<KToolBarButton *>( *it );
524 KToolBarButton * button = (KToolBarButton *)( *it );
525 if ( button )
526 button->setPixmap( _pixmap );
527}
528
529
530void KToolBar::setButtonIcon( int id, const QString& _icon )
531{
532 Id2WidgetMap::Iterator it = id2widget.find( id );
533 if ( it == id2widget.end() )
534 return;
535//US KToolBarButton * button = dynamic_cast<KToolBarButton *>( *it );
536 KToolBarButton * button = (KToolBarButton *)( *it );
537 if ( button )
538 button->setIcon( _icon );
539}
540
541void KToolBar::setButtonIconSet( int id, const QIconSet& iconset )
542{
543 Id2WidgetMap::Iterator it = id2widget.find( id );
544 if ( it == id2widget.end() )
545 return;
546//US KToolBarButton * button = dynamic_cast<KToolBarButton *>( *it );
547 KToolBarButton * button = (KToolBarButton *)( *it );
548 if ( button )
549 button->setIconSet( iconset );
550}
551
552
553void KToolBar::setDelayedPopup (int id , QPopupMenu *_popup, bool toggle )
554{
555 Id2WidgetMap::Iterator it = id2widget.find( id );
556 if ( it == id2widget.end() )
557 return;
558//US KToolBarButton * button = dynamic_cast<KToolBarButton *>( *it );
559 KToolBarButton * button = (KToolBarButton *)( *it );
560 if ( button )
561 button->setDelayedPopup( _popup, toggle );
562}
563
564
565void KToolBar::setAutoRepeat (int id, bool flag)
566{
567 Id2WidgetMap::Iterator it = id2widget.find( id );
568 if ( it == id2widget.end() )
569 return;
570//US KToolBarButton * button = dynamic_cast<KToolBarButton *>( *it );
571 KToolBarButton * button = (KToolBarButton *)( *it );
572 if ( button )
573 button->setAutoRepeat( flag );
574}
575
576
577void KToolBar::setToggle (int id, bool flag )
578{
579 Id2WidgetMap::Iterator it = id2widget.find( id );
580 if ( it == id2widget.end() )
581 return;
582//US KToolBarButton * button = dynamic_cast<KToolBarButton *>( *it );
583 KToolBarButton * button = (KToolBarButton *)( *it );
584 if ( button )
585 button->setToggle( flag );
586}
587
588
589void KToolBar::toggleButton (int id)
590{
591 Id2WidgetMap::Iterator it = id2widget.find( id );
592 if ( it == id2widget.end() )
593 return;
594//US KToolBarButton * button = dynamic_cast<KToolBarButton *>( *it );
595 KToolBarButton * button = (KToolBarButton *)( *it );
596 if ( button )
597 button->toggle();
598}
599
600
601void KToolBar::setButton (int id, bool flag)
602{
603 Id2WidgetMap::Iterator it = id2widget.find( id );
604 if ( it == id2widget.end() )
605 return;
606//US KToolBarButton * button = dynamic_cast<KToolBarButton *>( *it );
607 KToolBarButton * button = (KToolBarButton *)( *it );
608 if ( button )
609 button->on( flag );
610}
611
612
613bool KToolBar::isButtonOn (int id) const
614{
615 Id2WidgetMap::ConstIterator it = id2widget.find( id );
616 if ( it == id2widget.end() )
617 return false;
618//US KToolBarButton * button = dynamic_cast<KToolBarButton *>( *it );
619 KToolBarButton * button = (KToolBarButton *)( *it );
620 return button ? button->isOn() : false;
621}
622
623
624void KToolBar::setLinedText (int id, const QString& text)
625{
626 Id2WidgetMap::Iterator it = id2widget.find( id );
627 if ( it == id2widget.end() )
628 return;
629//US QLineEdit * lineEdit = dynamic_cast<QLineEdit *>( *it );
630 QLineEdit * lineEdit = (QLineEdit *)( *it );
631 if ( lineEdit )
632 lineEdit->setText( text );
633}
634
635
636QString KToolBar::getLinedText (int id) const
637{
638 Id2WidgetMap::ConstIterator it = id2widget.find( id );
639 if ( it == id2widget.end() )
640 return QString::null;
641//US QLineEdit * lineEdit = dynamic_cast<QLineEdit *>( *it );
642 QLineEdit * lineEdit = (QLineEdit *)( *it );
643 return lineEdit ? lineEdit->text() : QString::null;
644}
645
646
647void KToolBar::insertComboItem (int id, const QString& text, int index)
648{
649 Id2WidgetMap::Iterator it = id2widget.find( id );
650 if ( it == id2widget.end() )
651 return;
652//US QComboBox * comboBox = dynamic_cast<QComboBox *>( *it );
653 QComboBox * comboBox = (QComboBox *)( *it );
654 if (comboBox)
655 comboBox->insertItem( text, index );
656}
657
658void KToolBar::insertComboList (int id, const QStringList &list, int index)
659{
660 Id2WidgetMap::Iterator it = id2widget.find( id );
661 if ( it == id2widget.end() )
662 return;
663//US QComboBox * comboBox = dynamic_cast<QComboBox *>( *it );
664 QComboBox * comboBox = (QComboBox *)( *it );
665 if (comboBox)
666 comboBox->insertStringList( list, index );
667}
668
669
670void KToolBar::removeComboItem (int id, int index)
671{
672 Id2WidgetMap::Iterator it = id2widget.find( id );
673 if ( it == id2widget.end() )
674 return;
675//US QComboBox * comboBox = dynamic_cast<QComboBox *>( *it );
676 QComboBox * comboBox = (QComboBox *)( *it );
677 if (comboBox)
678 comboBox->removeItem( index );
679}
680
681
682void KToolBar::setCurrentComboItem (int id, int index)
683{
684 Id2WidgetMap::Iterator it = id2widget.find( id );
685 if ( it == id2widget.end() )
686 return;
687//US QComboBox * comboBox = dynamic_cast<QComboBox *>( *it );
688 QComboBox * comboBox = (QComboBox *)( *it );
689 if (comboBox)
690 comboBox->setCurrentItem( index );
691}
692
693
694void KToolBar::changeComboItem (int id, const QString& text, int index)
695{
696 Id2WidgetMap::Iterator it = id2widget.find( id );
697 if ( it == id2widget.end() )
698 return;
699//US QComboBox * comboBox = dynamic_cast<QComboBox *>( *it );
700 QComboBox * comboBox = (QComboBox *)( *it );
701 if (comboBox)
702 comboBox->changeItem( text, index );
703}
704
705
706void KToolBar::clearCombo (int id)
707{
708 Id2WidgetMap::Iterator it = id2widget.find( id );
709 if ( it == id2widget.end() )
710 return;
711//US QComboBox * comboBox = dynamic_cast<QComboBox *>( *it );
712 QComboBox * comboBox = (QComboBox *)( *it );
713 if (comboBox)
714 comboBox->clear();
715}
716
717
718QString KToolBar::getComboItem (int id, int index) const
719{
720 Id2WidgetMap::ConstIterator it = id2widget.find( id );
721 if ( it == id2widget.end() )
722 return QString::null;
723//US QComboBox * comboBox = dynamic_cast<QComboBox *>( *it );
724 QComboBox * comboBox = (QComboBox *)( *it );
725 return comboBox ? comboBox->text( index ) : QString::null;
726}
727
728
729KComboBox * KToolBar::getCombo(int id)
730{
731 Id2WidgetMap::Iterator it = id2widget.find( id );
732 if ( it == id2widget.end() )
733 return 0;
734//US return dynamic_cast<KComboBox *>( *it );
735 return (KComboBox *)( *it );
736}
737
738
739KLineEdit * KToolBar::getLined (int id)
740{
741 Id2WidgetMap::Iterator it = id2widget.find( id );
742 if ( it == id2widget.end() )
743 return 0;
744//US return dynamic_cast<KLineEdit *>( *it );
745 return (KLineEdit *)( *it );
746}
747
748
749KToolBarButton * KToolBar::getButton (int id)
750{
751 Id2WidgetMap::Iterator it = id2widget.find( id );
752 if ( it == id2widget.end() )
753 return 0;
754//US return dynamic_cast<KToolBarButton *>( *it );
755 return (KToolBarButton *)( *it );
756}
757
758
759void KToolBar::alignItemRight (int id, bool right )
760{
761 Id2WidgetMap::Iterator it = id2widget.find( id );
762 if ( it == id2widget.end() )
763 return;
764 if ( rightAligned && !right && (*it) == rightAligned )
765 rightAligned = 0;
766 if ( (*it) && right )
767 rightAligned = (*it);
768}
769
770
771QWidget *KToolBar::getWidget (int id)
772{
773 Id2WidgetMap::Iterator it = id2widget.find( id );
774 return ( it == id2widget.end() ) ? 0 : (*it);
775}
776
777
778void KToolBar::setItemAutoSized (int id, bool yes )
779{
780 QWidget *w = getWidget(id);
781 if ( w && yes )
782 setStretchableWidget( w );
783}
784
785
786void KToolBar::clear ()
787{
788 QToolBar::clear();
789 widget2id.clear();
790 id2widget.clear();
791}
792
793
794void KToolBar::removeItem(int id)
795{
796 Id2WidgetMap::Iterator it = id2widget.find( id );
797 if ( it == id2widget.end() )
798 {
799 kdDebug(220) << "KToolBar::removeItem item " << id << " not found" << endl;
800 return;
801 }
802 QWidget * w = (*it);
803 id2widget.remove( id );
804 widget2id.remove( w );
805 widgets.removeRef( w );
806 delete w;
807}
808
809
810void KToolBar::removeItemDelayed(int id)
811{
812 Id2WidgetMap::Iterator it = id2widget.find( id );
813 if ( it == id2widget.end() )
814 {
815 kdDebug(220) << "KToolBar::removeItem item " << id << " not found" << endl;
816 return;
817 }
818 QWidget * w = (*it);
819 id2widget.remove( id );
820 widget2id.remove( w );
821 widgets.removeRef( w );
822
823 w->blockSignals(true);
824 d->idleButtons.append(w);
825 layoutTimer->start( 50, TRUE );
826}
827
828
829void KToolBar::hideItem (int id)
830{
831 QWidget *w = getWidget(id);
832 if ( w )
833 w->hide();
834}
835
836
837void KToolBar::showItem (int id)
838{
839 QWidget *w = getWidget(id);
840 if ( w )
841 w->show();
842}
843
844
845int KToolBar::itemIndex (int id)
846{
847 QWidget *w = getWidget(id);
848 return w ? widgets.findRef(w) : -1;
849}
850
851
852void KToolBar::setFullSize(bool flag )
853{
854 setHorizontalStretchable( flag );
855 setVerticalStretchable( flag );
856}
857
858
859bool KToolBar::fullSize() const
860{
861 return isHorizontalStretchable() || isVerticalStretchable();
862}
863
864
865void KToolBar::enableMoving(bool flag )
866{
867//US setMovingEnabled(flag);
868 this->mainWindow()->setToolBarsMovable(flag);
869}
870
871
872void KToolBar::setBarPos (BarPosition bpos)
873{
874 if ( !mainWindow() )
875 return;
876//US mainWindow()->moveDockWindow( this, (Dock)bpos );
877 mainWindow()->moveToolBar( this, (QMainWindow::ToolBarDock)bpos );
878}
879
880
881KToolBar::BarPosition KToolBar::barPos()
882{
883 if ( !(QMainWindow*)mainWindow() )
884 return KToolBar::Top;
885//US Dock dock;
886 QMainWindow::ToolBarDock dock;
887 int dm1, dm2;
888 bool dm3;
889 ((QMainWindow*)mainWindow())->getLocation( (QToolBar*)this, dock, dm1, dm3, dm2 );
890//US if ( dock == DockUnmanaged ) {
891 if ( dock == QMainWindow::Unmanaged ) {
892 return (KToolBar::BarPosition)Top;
893 }
894 return (BarPosition)dock;
895}
896
897
898bool KToolBar::enable(BarStatus stat)
899{
900 bool mystat = isVisible();
901
902 if ( (stat == Toggle && mystat) || stat == Hide )
903 hide();
904 else
905 show();
906
907 return isVisible() == mystat;
908}
909
910
911void KToolBar::setMaxHeight ( int h )
912{
913 setMaximumHeight( h );
914}
915
916int KToolBar::maxHeight()
917{
918 return maximumHeight();
919}
920
921
922void KToolBar::setMaxWidth (int dw)
923{
924 setMaximumWidth( dw );
925}
926
927
928int KToolBar::maxWidth()
929{
930 return maximumWidth();
931}
932
933
934void KToolBar::setTitle (const QString& _title)
935{
936 setLabel( _title );
937}
938
939
940void KToolBar::enableFloating (bool )
941{
942}
943
944
945void KToolBar::setIconText(IconText it)
946{
947 setIconText( it, true );
948}
949
950
951void KToolBar::setIconText(IconText icontext, bool update)
952{
953 bool doUpdate=false;
954
955 if (icontext != d->m_iconText) {
956 d->m_iconText = icontext;
957 doUpdate=true;
958 }
959
960 if (update == false)
961 return;
962
963 if (doUpdate)
964 emit modechange(); // tell buttons what happened
965
966 // ugly hack to force a QMainWindow::triggerLayout( TRUE )
967 if ( mainWindow() ) {
968 QMainWindow *mw = mainWindow();
969 mw->setUpdatesEnabled( FALSE );
970 mw->setToolBarsMovable( !mw->toolBarsMovable() );
971 mw->setToolBarsMovable( !mw->toolBarsMovable() );
972 mw->setUpdatesEnabled( TRUE );
973 }
974}
975
976
977KToolBar::IconText KToolBar::iconText() const
978{
979 return d->m_iconText;
980}
981
982
983void KToolBar::setIconSize(int size)
984{
985 setIconSize( size, true );
986}
987
988void KToolBar::setIconSize(int size, bool update)
989{
990 bool doUpdate=false;
991
992 if ( size != d->m_iconSize ) {
993 d->m_iconSize = size;
994 doUpdate=true;
995 }
996
997 if (update == false)
998 return;
999
1000 if (doUpdate)
1001 emit modechange(); // tell buttons what happened
1002
1003 // ugly hack to force a QMainWindow::triggerLayout( TRUE )
1004 if ( mainWindow() ) {
1005 QMainWindow *mw = mainWindow();
1006 mw->setUpdatesEnabled( FALSE );
1007 mw->setToolBarsMovable( !mw->toolBarsMovable() );
1008 mw->setToolBarsMovable( !mw->toolBarsMovable() );
1009 mw->setUpdatesEnabled( TRUE );
1010 }
1011}
1012
1013
1014int KToolBar::iconSize() const
1015{
1016/*US
1017 if ( !d->m_iconSize ) // default value?
1018 {
1019 if (!::qstrcmp(QObject::name(), "mainToolBar"))
1020 return KGlobal::iconLoader()->currentSize(KIcon::MainToolbar);
1021 else
1022 return KGlobal::iconLoader()->currentSize(KIcon::Toolbar);
1023 }
1024 return d->m_iconSize;
1025*/
1026 int ret = 18;
1027 if ( QApplication::desktop()->width() > 320 && QApplication::desktop()->width() < 650 )
1028 ret = 30;
1029 return ret;
1030}
1031
1032
1033void KToolBar::setEnableContextMenu(bool enable )
1034{
1035 d->m_enableContext = enable;
1036}
1037
1038
1039bool KToolBar::contextMenuEnabled() const
1040{
1041 return d->m_enableContext;
1042}
1043
1044
1045void KToolBar::setItemNoStyle(int id, bool no_style )
1046{
1047 Id2WidgetMap::Iterator it = id2widget.find( id );
1048 if ( it == id2widget.end() )
1049 return;
1050//US KToolBarButton * button = dynamic_cast<KToolBarButton *>( *it );
1051 KToolBarButton * button = (KToolBarButton *)( *it );
1052 if (button)
1053 button->setNoStyle( no_style );
1054}
1055
1056
1057void KToolBar::setFlat (bool flag)
1058{
1059 if ( !mainWindow() )
1060 return;
1061 if ( flag )
1062//US mainWindow()->moveDockWindow( this, DockMinimized );
1063 mainWindow()->moveToolBar( this, QMainWindow::Minimized );
1064 else
1065//US mainWindow()->moveDockWindow( this, DockTop );
1066 mainWindow()->moveToolBar( this, QMainWindow::Top );
1067 // And remember to save the new look later
1068/*US
1069 if ( mainWindow()->inherits( "KMainWindow" ) )
1070 static_cast<KMainWindow *>(mainWindow())->setSettingsDirty();
1071*/
1072}
1073
1074
1075int KToolBar::count() const
1076{
1077 return id2widget.count();
1078}
1079
1080
1081void KToolBar::saveState()
1082{
1083/*US
1084 // first, try to save to the xml file
1085 if ( d->m_xmlguiClient && !d->m_xmlguiClient->xmlFile().isEmpty() ) {
1086 // go down one level to get to the right tags
1087 QDomElement elem = d->m_xmlguiClient->domDocument().documentElement().toElement();
1088 elem = elem.firstChild().toElement();
1089 QString barname(!::qstrcmp(name(), "unnamed") ? "mainToolBar" : name());
1090 QDomElement current;
1091 // now try to find our toolbar
1092 d->modified = false;
1093 for( ; !elem.isNull(); elem = elem.nextSibling().toElement() ) {
1094 current = elem;
1095
1096 if ( current.tagName().lower() != "toolbar" )
1097 continue;
1098
1099 QString curname(current.attribute( "name" ));
1100
1101 if ( curname == barname ) {
1102 saveState( current );
1103 break;
1104 }
1105 }
1106 // if we didn't make changes, then just return
1107 if ( !d->modified )
1108 return;
1109
1110 // now we load in the (non-merged) local file
1111 QString local_xml(KXMLGUIFactory::readConfigFile(d->m_xmlguiClient->xmlFile(), true, d->m_xmlguiClient->instance()));
1112 QDomDocument local;
1113 local.setContent(local_xml);
1114
1115 // make sure we don't append if this toolbar already exists locally
1116 bool just_append = true;
1117 elem = local.documentElement().toElement();
1118 KXMLGUIFactory::removeDOMComments( elem );
1119 elem = elem.firstChild().toElement();
1120 for( ; !elem.isNull(); elem = elem.nextSibling().toElement() ) {
1121 if ( elem.tagName().lower() != "toolbar" )
1122 continue;
1123
1124 QString curname(elem.attribute( "name" ));
1125
1126 if ( curname == barname ) {
1127 just_append = false;
1128 local.documentElement().replaceChild( current, elem );
1129 break;
1130 }
1131 }
1132
1133 if (just_append)
1134 local.documentElement().appendChild( current );
1135
1136 KXMLGUIFactory::saveConfigFile(local, d->m_xmlguiClient->localXMLFile(), d->m_xmlguiClient->instance() );
1137
1138 return;
1139 }
1140*/
1141 // if that didn't work, we save to the config file
1142 KConfig *config = KGlobal::config();
1143 saveSettings(config, QString::null);
1144 config->sync();
1145}
1146
1147QString KToolBar::settingsGroup()
1148{
1149 QString configGroup;
1150 if (!::qstrcmp(name(), "unnamed") || !::qstrcmp(name(), "mainToolBar"))
1151 configGroup = "Toolbar style";
1152 else
1153 configGroup = QString(name()) + " Toolbar style";
1154 if ( this->mainWindow() )
1155 {
1156 configGroup.prepend(" ");
1157 configGroup.prepend( this->mainWindow()->name() );
1158 }
1159 return configGroup;
1160}
1161
1162void KToolBar::saveSettings(KConfig *config, const QString &_configGroup)
1163{
1164 QString configGroup = _configGroup;
1165 if (configGroup.isEmpty())
1166 configGroup = settingsGroup();
1167 //kdDebug(220) << "KToolBar::saveSettings group=" << _configGroup << " -> " << configGroup << endl;
1168
1169 QString position, icontext;
1170 int index;
1171 getAttributes( position, icontext, index );
1172
1173 //kdDebug(220) << "KToolBar::saveSettings " << name() << " newLine=" << newLine << endl;
1174
1175 KConfigGroupSaver saver(config, configGroup);
1176
1177 if ( position != d->PositionDefault )
1178 config->writeEntry("Position", position);
1179 else
1180 config->deleteEntry("Position");
1181
1182 if ( icontext != d->IconTextDefault )
1183 config->writeEntry("IconText", icontext);
1184 else
1185 config->deleteEntry("IconText");
1186
1187 if ( iconSize() != d->IconSizeDefault )
1188 config->writeEntry("IconSize", iconSize());
1189 else
1190 config->deleteEntry("IconSize");
1191
1192 if ( isHidden() != d->HiddenDefault )
1193 config->writeEntry("Hidden", isHidden());
1194 else
1195 config->deleteEntry("Hidden");
1196
1197 if ( index != d->IndexDefault )
1198 config->writeEntry( "Index", index );
1199 else
1200 config->deleteEntry("Index");
1201//US the older version of KDE (used on the Zaurus) has no Offset property
1202/* if ( offset() != d->OffsetDefault )
1203 config->writeEntry( "Offset", offset() );
1204 else
1205*/
1206 config->deleteEntry("Offset");
1207
1208//US the older version of KDE (used on the Zaurus) has no NewLine property
1209/*
1210 if ( newLine() != d->NewLineDefault )
1211 config->writeEntry( "NewLine", newLine() );
1212 else
1213*/
1214 config->deleteEntry("NewLine");
1215}
1216
1217void KToolBar::setXMLGUIClient( KXMLGUIClient *client )
1218{
1219 d->m_xmlguiClient = client;
1220}
1221
1222void KToolBar::setText( const QString & txt )
1223{
1224//US setLabel( txt + " ( " + kapp->caption() + " ) " );
1225 setLabel( txt + " ( " + KGlobal::getAppName() + " ) " );
1226}
1227
1228
1229QString KToolBar::text() const
1230{
1231 return label();
1232}
1233
1234
1235void KToolBar::doConnections( KToolBarButton *button )
1236{
1237 connect(button, SIGNAL(clicked(int)), this, SIGNAL( clicked( int ) ) );
1238 connect(button, SIGNAL(doubleClicked(int)), this, SIGNAL( doubleClicked( int ) ) );
1239 connect(button, SIGNAL(released(int)), this, SIGNAL( released( int ) ) );
1240 connect(button, SIGNAL(pressed(int)), this, SIGNAL( pressed( int ) ) );
1241 connect(button, SIGNAL(toggled(int)), this, SIGNAL( toggled( int ) ) );
1242 connect(button, SIGNAL(highlighted(int, bool)), this, SIGNAL( highlighted( int, bool ) ) );
1243}
1244
1245void KToolBar::mousePressEvent ( QMouseEvent *m )
1246{
1247 if ( !mainWindow() )
1248 return;
1249 QMainWindow *mw = mainWindow();
1250 if ( mw->toolBarsMovable() && d->m_enableContext ) {
1251 if ( m->button() == RightButton ) {
1252 int i = contextMenu()->exec( m->globalPos(), 0 );
1253 switch ( i ) {
1254 case -1:
1255 return; // popup cancelled
1256 case CONTEXT_LEFT:
1257//US mw->moveDockWindow( this, DockLeft );
1258 mw->moveToolBar( this, QMainWindow::Left );
1259 break;
1260 case CONTEXT_RIGHT:
1261//US mw->moveDockWindow( this, DockRight );
1262 mw->moveToolBar( this, QMainWindow::Right );
1263 break;
1264 case CONTEXT_TOP:
1265//US mw->moveDockWindow( this, DockTop );
1266 mw->moveToolBar( this, QMainWindow::Top );
1267 break;
1268 case CONTEXT_BOTTOM:
1269//US mw->moveDockWindow( this, DockBottom );
1270 mw->moveToolBar( this, QMainWindow::Bottom );
1271 break;
1272 case CONTEXT_FLOAT:
1273 break;
1274 case CONTEXT_FLAT:
1275//US mw->moveDockWindow( this, DockMinimized );
1276 mw->moveToolBar( this, QMainWindow::Minimized );
1277 break;
1278 case CONTEXT_ICONS:
1279 setIconText( IconOnly );
1280 break;
1281 case CONTEXT_TEXTRIGHT:
1282 setIconText( IconTextRight );
1283 break;
1284 case CONTEXT_TEXT:
1285 setIconText( TextOnly );
1286 break;
1287 case CONTEXT_TEXTUNDER:
1288 setIconText( IconTextBottom );
1289 break;
1290 default:
1291 if ( i >= CONTEXT_ICONSIZES )
1292 setIconSize( i - CONTEXT_ICONSIZES );
1293 else
1294 return; // assume this was an action handled elsewhere, no need for setSettingsDirty()
1295 }
1296/*US
1297 if ( mw->inherits("KMainWindow") )
1298 static_cast<KMainWindow *>(mw)->setSettingsDirty();
1299*/
1300 }
1301 }
1302}
1303
1304
1305void KToolBar::rebuildLayout()
1306{
1307
1308 for(QWidget *w=d->idleButtons.first(); w; w=d->idleButtons.next())
1309 w->blockSignals(false);
1310 d->idleButtons.clear();
1311
1312 layoutTimer->stop();
1313 QApplication::sendPostedEvents( this, QEvent::ChildInserted );
1314 QBoxLayout *l = boxLayout();
1315 l->setMargin( 1 );
1316 // clear the old layout
1317 QLayoutIterator it = l->iterator();
1318
1319 while ( it.current() ) {
1320 it.deleteCurrent();
1321 }
1322 for ( QWidget *w = widgets.first(); w; w = widgets.next() ) {
1323 if ( w == rightAligned ) {
1324 continue;
1325 }
1326 if ( w->inherits( "KToolBarSeparator" ) &&
1327 !( (KToolBarSeparator*)w )->showLine() ) {
1328 l->addSpacing( 6 );
1329 w->hide();
1330 continue;
1331 }
1332 if ( w->inherits( "QPopupMenu" ) )
1333 continue;
1334 l->addWidget( w );
1335 w->show();
1336 }
1337 if ( rightAligned ) {
1338 l->addStretch();
1339 l->addWidget( rightAligned );
1340 rightAligned->show();
1341 }
1342
1343 if ( fullSize() ) {
1344 // This code sucks. It makes the last combo in a toolbar VERY big (e.g. zoom combo in kword).
1345 //if ( !stretchableWidget && widgets.last() &&
1346 // !widgets.last()->inherits( "QButton" ) && !widgets.last()->inherits( "KAnimWidget" ) )
1347 // setStretchableWidget( widgets.last() );
1348 if ( !rightAligned )
1349 l->addStretch();
1350 if ( stretchableWidget )
1351 l->setStretchFactor( stretchableWidget, 10 );
1352 }
1353 l->invalidate();
1354 QApplication::postEvent( this, new QEvent( QEvent::LayoutHint ) );
1355 //#endif //DESKTOP_VERSION
1356}
1357
1358void KToolBar::childEvent( QChildEvent *e )
1359{
1360
1361 if ( e->child()->isWidgetType() ) {
1362 QWidget * w = (QWidget*)e->child();
1363 if ( e->type() == QEvent::ChildInserted ) {
1364 if ( !e->child()->inherits( "QPopupMenu" ) &&
1365 ::qstrcmp( "qt_dockwidget_internal", e->child()->name() ) != 0 ) {
1366
1367 // prevent items that have been explicitly inserted by insert*() from
1368 // being inserted again
1369 if ( !widget2id.contains( w ) )
1370 {
1371 int dummy = -1;
1372 insertWidgetInternal( w, dummy, -1 );
1373 }
1374 }
1375 } else {
1376 removeWidgetInternal( w );
1377 }
1378 if ( isVisibleTo( 0 ) )
1379 {
1380 QBoxLayout *l = boxLayout();
1381 // QLayout *l = layout();
1382
1383 // clear the old layout so that we don't get unnecassery layout
1384 // changes till we have rebuild the thing
1385 QLayoutIterator it = l->iterator();
1386 while ( it.current() ) {
1387 it.deleteCurrent();
1388 }
1389 layoutTimer->start( 50, TRUE );
1390 }
1391 }
1392 QToolBar::childEvent( e );
1393}
1394
1395void KToolBar::insertWidgetInternal( QWidget *w, int &index, int id )
1396{
1397 // we can't have it in widgets, or something is really wrong
1398 //widgets.removeRef( w );
1399
1400 connect( w, SIGNAL( destroyed() ),
1401 this, SLOT( widgetDestroyed() ) );
1402 if ( index == -1 || index > (int)widgets.count() ) {
1403 widgets.append( w );
1404 index = (int)widgets.count();
1405 }
1406 else
1407 widgets.insert( index, w );
1408 if ( id == -1 )
1409 id = id2widget.count();
1410 id2widget.insert( id, w );
1411 widget2id.insert( w, id );
1412}
1413
1414void KToolBar::showEvent( QShowEvent *e )
1415{
1416 QToolBar::showEvent( e );
1417 rebuildLayout();
1418}
1419
1420void KToolBar::setStretchableWidget( QWidget *w )
1421{
1422 QToolBar::setStretchableWidget( w );
1423 stretchableWidget = w;
1424}
1425
1426QSizePolicy KToolBar::sizePolicy() const
1427{
1428 if ( orientation() == Horizontal )
1429 return QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed );
1430 else
1431 return QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Expanding );
1432}
1433
1434QSize KToolBar::sizeHint() const
1435{
1436 return QToolBar::sizeHint();
1437#if 0
1438 QWidget::polish();
1439 static int iii = 0;
1440 ++iii;
1441 qDebug("++++++++ KToolBar::sizeHint() %d ", iii );
1442 int margin = static_cast<QWidget*>(ncThis)->layout()->margin();
1443 switch( barPos() )
1444 {
1445 case KToolBar::Top:
1446 case KToolBar::Bottom:
1447 for ( QWidget *w = widgets.first(); w; w =widgets.next() )
1448 {
1449 if ( w->inherits( "KToolBarSeparator" ) &&
1450 !( static_cast<KToolBarSeparator*>(w)->showLine() ) )
1451 {
1452 minSize += QSize(6, 0);
1453 }
1454 else
1455 {
1456 QSize sh = w->sizeHint();
1457 if (!sh.isValid())
1458 sh = w->minimumSize();
1459 minSize = minSize.expandedTo(QSize(0, sh.height()));
1460 minSize += QSize(sh.width()+1, 0);
1461 }
1462 }
1463/*US
1464 minSize += QSize(QApplication::style().pixelMetric( QStyle::PM_DockWindowHandleExtent ), 0);
1465*/
1466 minSize += QSize(margin*2, margin*2);
1467 break;
1468
1469 case KToolBar::Left:
1470 case KToolBar::Right:
1471 for ( QWidget *w = widgets.first(); w; w = widgets.next() )
1472 {
1473 if ( w->inherits( "KToolBarSeparator" ) &&
1474 !( static_cast<KToolBarSeparator*>(w)->showLine() ) )
1475 {
1476 minSize += QSize(0, 6);
1477 }
1478 else
1479 {
1480 QSize sh = w->sizeHint();
1481 if (!sh.isValid())
1482 sh = w->minimumSize();
1483 minSize = minSize.expandedTo(QSize(sh.width(), 0));
1484 minSize += QSize(0, sh.height()+1);
1485 }
1486 }
1487/*US
1488 minSize += QSize(0, QApplication::style().pixelMetric( QStyle::PM_DockWindowHandleExtent ));
1489*/
1490 minSize += QSize(margin*2, margin*2);
1491 break;
1492
1493 default:
1494 minSize = QToolBar::sizeHint();
1495 break;
1496 }
1497 return minSize;
1498#endif
1499}
1500
1501QSize KToolBar::minimumSize() const
1502{
1503 return minimumSizeHint();
1504}
1505
1506QSize KToolBar::minimumSizeHint() const
1507{
1508 return sizeHint();
1509}
1510
1511bool KToolBar::highlight() const
1512{
1513 return d->m_highlight;
1514}
1515
1516void KToolBar::hide()
1517{
1518 QToolBar::hide();
1519}
1520
1521void KToolBar::show()
1522{
1523 QToolBar::show();
1524}
1525
1526void KToolBar::resizeEvent( QResizeEvent *e )
1527{
1528 bool b = isUpdatesEnabled();
1529 setUpdatesEnabled( FALSE );
1530 QToolBar::resizeEvent( e );
1531 if (b)
1532 d->repaintTimer.start( 100, true );
1533}
1534
1535void KToolBar::slotIconChanged(int group)
1536{
1537 if ((group != KIcon::Toolbar) && (group != KIcon::MainToolbar))
1538 return;
1539 if ((group == KIcon::MainToolbar) != !::qstrcmp(name(), "mainToolBar"))
1540 return;
1541
1542 emit modechange();
1543 if (isVisible())
1544 updateGeometry();
1545}
1546
1547void KToolBar::slotReadConfig()
1548{
1549 //kdDebug(220) << "KToolBar::slotReadConfig" << endl;
1550 // Read appearance settings (hmm, we used to do both here,
1551 // but a well behaved application will call applyMainWindowSettings
1552 // anyway, right ?)
1553 applyAppearanceSettings(KGlobal::config(), QString::null );
1554}
1555
1556void KToolBar::slotAppearanceChanged()
1557{
1558 // Read appearance settings from global file.
1559 applyAppearanceSettings(KGlobal::config(), QString::null, true /* lose local settings */ );
1560 // And remember to save the new look later
1561/*US
1562 if ( mainWindow() && mainWindow()->inherits( "KMainWindow" ) )
1563 static_cast<KMainWindow *>(mainWindow())->setSettingsDirty();
1564*/
1565}
1566
1567//static
1568bool KToolBar::highlightSetting()
1569{
1570 QString grpToolbar(QString::fromLatin1("Toolbar style"));
1571 KConfigGroupSaver saver(KGlobal::config(), grpToolbar);
1572 return KGlobal::config()->readBoolEntry(QString::fromLatin1("Highlighting"),true);
1573}
1574
1575//static
1576bool KToolBar::transparentSetting()
1577{
1578 QString grpToolbar(QString::fromLatin1("Toolbar style"));
1579 KConfigGroupSaver saver(KGlobal::config(), grpToolbar);
1580 return KGlobal::config()->readBoolEntry(QString::fromLatin1("TransparentMoving"),true);
1581}
1582
1583//static
1584KToolBar::IconText KToolBar::iconTextSetting()
1585{
1586 QString grpToolbar(QString::fromLatin1("Toolbar style"));
1587 KConfigGroupSaver saver(KGlobal::config(), grpToolbar);
1588 QString icontext = KGlobal::config()->readEntry(QString::fromLatin1("IconText"),QString::fromLatin1("IconOnly"));
1589 if ( icontext == "IconTextRight" )
1590 return IconTextRight;
1591 else if ( icontext == "IconTextBottom" )
1592 return IconTextBottom;
1593 else if ( icontext == "TextOnly" )
1594 return TextOnly;
1595 else
1596 return IconOnly;
1597}
1598
1599void KToolBar::applyAppearanceSettings(KConfig *config, const QString &_configGroup, bool forceGlobal)
1600{
1601 QString configGroup = _configGroup.isEmpty() ? settingsGroup() : _configGroup;
1602 //kdDebug(220) << "KToolBar::applyAppearanceSettings: configGroup=" << configGroup << endl;
1603 // We have application-specific settings in the XML file,
1604 // and nothing in the application's config file
1605 // -> don't apply the global defaults, the XML ones are preferred
1606 // See applySettings for a full explanation
1607/*US :we do not support xml files
1608 if ( d->m_xmlguiClient && !d->m_xmlguiClient->xmlFile().isEmpty() &&
1609 !config->hasGroup(configGroup) )
1610 {
1611 //kdDebug(220) << "skipping global defaults, using XML ones instead" << endl;
1612 return;
1613 }
1614*/
1615 if ( !config->hasGroup(configGroup) )
1616 {
1617 //kdDebug(220) << "skipping global defaults, using XML ones instead" << endl;
1618 return;
1619 }
1620
1621
1622 KConfig *gconfig = KGlobal::config();
1623/*US
1624 static const QString &attrIconText = KGlobal::staticQString("IconText");
1625 static const QString &attrHighlight = KGlobal::staticQString("Highlighting");
1626 static const QString &attrTrans = KGlobal::staticQString("TransparentMoving");
1627 static const QString &attrSize = KGlobal::staticQString("IconSize");
1628*/
1629 // we actually do this in two steps.
1630 // First, we read in the global styles [Toolbar style] (from the KControl module).
1631 // Then, if the toolbar is NOT 'mainToolBar', we will also try to read in [barname Toolbar style]
1632 bool highlight;
1633 int transparent;
1634 QString icontext;
1635 int iconsize = 0;
1636
1637 // this is the first iteration
1638 QString grpToolbar(QString::fromLatin1("Toolbar style"));
1639 { // start block for KConfigGroupSaver
1640 KConfigGroupSaver saver(gconfig, grpToolbar);
1641
1642 // first, get the generic settings
1643//US highlight = gconfig->readBoolEntry(attrHighlight, true);
1644 highlight = gconfig->readBoolEntry("Highlighting", true);
1645//US transparent = gconfig->readBoolEntry(attrTrans, true);
1646 transparent = gconfig->readBoolEntry("TransparentMoving", true);
1647
1648 // we read in the IconText property *only* if we intend on actually
1649 // honoring it
1650 if (d->m_honorStyle)
1651//US d->IconTextDefault = gconfig->readEntry(attrIconText, d->IconTextDefault);
1652 d->IconTextDefault = gconfig->readEntry("IconText", d->IconTextDefault);
1653 else
1654 d->IconTextDefault = "IconOnly";
1655
1656 // Use the default icon size for toolbar icons.
1657//US d->IconSizeDefault = gconfig->readNumEntry(attrSize, d->IconSizeDefault);
1658 d->IconSizeDefault = gconfig->readNumEntry("IconSize", d->IconSizeDefault);
1659
1660 if ( !forceGlobal && config->hasGroup(configGroup) )
1661 {
1662 config->setGroup(configGroup);
1663
1664 // first, get the generic settings
1665//US highlight = config->readBoolEntry(attrHighlight, highlight);
1666 highlight = config->readBoolEntry("Highlighting", highlight);
1667//US transparent = config->readBoolEntry(attrTrans, transparent);
1668 transparent = config->readBoolEntry("TransparentMoving", transparent);
1669 // now we always read in the IconText property
1670//US icontext = config->readEntry(attrIconText, d->IconTextDefault);
1671 icontext = config->readEntry("IconText", d->IconTextDefault);
1672
1673 // now get the size
1674//US iconsize = config->readNumEntry(attrSize, d->IconSizeDefault);
1675 iconsize = config->readNumEntry("IconSize", d->IconSizeDefault);
1676 }
1677 else
1678 {
1679 iconsize = d->IconSizeDefault;
1680 icontext = d->IconTextDefault;
1681 }
1682
1683 // revert back to the old group
1684 } // end block for KConfigGroupSaver
1685
1686 bool doUpdate = false;
1687
1688 IconText icon_text;
1689 if ( icontext == "IconTextRight" )
1690 icon_text = IconTextRight;
1691 else if ( icontext == "IconTextBottom" )
1692 icon_text = IconTextBottom;
1693 else if ( icontext == "TextOnly" )
1694 icon_text = TextOnly;
1695 else
1696 icon_text = IconOnly;
1697
1698 // check if the icon/text has changed
1699 if (icon_text != d->m_iconText) {
1700 //kdDebug(220) << "KToolBar::applyAppearanceSettings setIconText " << icon_text << endl;
1701 setIconText(icon_text, false);
1702 doUpdate = true;
1703 }
1704
1705 // ...and check if the icon size has changed
1706 if (iconsize != d->m_iconSize) {
1707 setIconSize(iconsize, false);
1708 doUpdate = true;
1709 }
1710
1711 QMainWindow *mw = mainWindow();
1712
1713 // ...and if we should highlight
1714 if ( highlight != d->m_highlight ) {
1715 d->m_highlight = highlight;
1716 doUpdate = true;
1717 }
1718
1719 // ...and if we should move transparently
1720 if ( mw && transparent != (!mw->opaqueMoving()) ) {
1721 mw->setOpaqueMoving( !transparent );
1722 }
1723
1724 if (doUpdate)
1725 emit modechange(); // tell buttons what happened
1726 if (isVisible ())
1727 updateGeometry();
1728}
1729
1730void KToolBar::applySettings(KConfig *config, const QString &_configGroup)
1731{
1732 //kdDebug(220) << "KToolBar::applySettings group=" << _configGroup << endl;
1733
1734 QString configGroup = _configGroup.isEmpty() ? settingsGroup() : _configGroup;
1735
1736 /*
1737 Let's explain this a bit more in details.
1738 The order in which we apply settings is :
1739 Global config / <appnamerc> user settings if no XMLGUI is used
1740 Global config / App-XML attributes / <appnamerc> user settings if XMLGUI is used
1741
1742 So in the first case, we simply read everything from KConfig as below,
1743 but in the second case we don't do anything here if there is no app-specific config,
1744 and the XMLGUI uses the static methods of this class to get the global defaults.
1745
1746 Global config doesn't include position (index, offset, newline and hidden/shown).
1747 */
1748
1749 // First the appearance stuff - the one which has a global config
1750 applyAppearanceSettings( config, _configGroup );
1751
1752 // ...and now the position stuff
1753 if ( config->hasGroup(configGroup) )
1754 {
1755 KConfigGroupSaver cgs(config, configGroup);
1756/*US
1757 static const QString &attrPosition = KGlobal::staticQString("Position");
1758 static const QString &attrIndex = KGlobal::staticQString("Index");
1759 static const QString &attrOffset = KGlobal::staticQString("Offset");
1760 static const QString &attrNewLine = KGlobal::staticQString("NewLine");
1761 static const QString &attrHidden = KGlobal::staticQString("Hidden");
1762
1763 QString position = config->readEntry(attrPosition, d->PositionDefault);
1764 int index = config->readNumEntry(attrIndex, d->IndexDefault);
1765 int offset = config->readNumEntry(attrOffset, d->OffsetDefault);
1766 bool newLine = config->readBoolEntry(attrNewLine, d->NewLineDefault);
1767 bool hidden = config->readBoolEntry(attrHidden, d->HiddenDefault);
1768*/
1769
1770 QString position = config->readEntry("Position", d->PositionDefault);
1771 int index = config->readNumEntry("Index", d->IndexDefault);
1772 int offset = config->readNumEntry("Offset", d->OffsetDefault);
1773 bool newLine = config->readBoolEntry("NewLine", d->NewLineDefault);
1774 bool hidden = config->readBoolEntry("Hidden", d->HiddenDefault);
1775
1776/*US Dock pos(DockTop);
1777 if ( position == "Top" )
1778 pos = DockTop;
1779 else if ( position == "Bottom" )
1780 pos = DockBottom;
1781 else if ( position == "Left" )
1782 pos = DockLeft;
1783 else if ( position == "Right" )
1784 pos = DockRight;
1785 else if ( position == "Floating" )
1786 pos = DockTornOff;
1787 else if ( position == "Flat" )
1788 pos = DockMinimized;
1789*/
1790 QMainWindow::ToolBarDock pos(QMainWindow::Top);
1791 if ( position == "Top" )
1792 pos = QMainWindow::Top;
1793 else if ( position == "Bottom" )
1794 pos = QMainWindow::Bottom;
1795 else if ( position == "Left" )
1796 pos = QMainWindow::Left;
1797 else if ( position == "Right" )
1798 pos = QMainWindow::Right;
1799 else if ( position == "Floating" )
1800 pos = QMainWindow::TornOff;
1801 else if ( position == "Flat" )
1802 pos = QMainWindow::Minimized;
1803
1804 //kdDebug(220) << "KToolBar::applySettings hidden=" << hidden << endl;
1805 if (hidden)
1806 hide();
1807 else
1808 show();
1809
1810 if ( mainWindow() )
1811 {
1812 QMainWindow *mw = mainWindow();
1813
1814 //kdDebug(220) << "KToolBar::applySettings updating ToolbarInfo" << endl;
1815 d->toolBarInfo = KToolBarPrivate::ToolBarInfo( pos, index, newLine, offset );
1816
1817 // moveDockWindow calls QDockArea which does a reparent() on us with
1818 // showIt = true, so we loose our visibility status
1819 bool doHide = isHidden();
1820
1821//US mw->moveDockWindow( this, pos, newLine, index, offset );
1822 mw->moveToolBar( this, pos, newLine, index, offset );
1823
1824 //kdDebug(220) << "KToolBar::applySettings " << name() << " moveDockWindow with pos=" << pos << " newLine=" << newLine << " idx=" << index << " offs=" << offset << endl;
1825 if ( doHide )
1826 hide();
1827 }
1828 if (isVisible ())
1829 updateGeometry();
1830 }
1831}
1832
1833bool KToolBar::event( QEvent *e )
1834{
1835 if ( (e->type() == QEvent::LayoutHint) && isUpdatesEnabled() )
1836 d->repaintTimer.start( 100, true );
1837
1838 if (e->type() == QEvent::ChildInserted )
1839 {
1840 // By pass QToolBar::event,
1841 // it will show() the inserted child and we don't want to
1842 // do that until we have rebuild the layout.
1843 childEvent((QChildEvent *)e);
1844 return true;
1845 }
1846
1847 return QToolBar::event( e );
1848}
1849
1850void KToolBar::slotRepaint()
1851{
1852 setUpdatesEnabled( FALSE );
1853 // Send a resizeEvent to update the "toolbar extension arrow"
1854 // (The button you get when your toolbar-items don't fit in
1855 // the available space)
1856 QResizeEvent ev(size(), size());
1857 resizeEvent(&ev);
1858 //#ifdef DESKTOP_VERSION
1859 QApplication::sendPostedEvents( this, QEvent::LayoutHint );
1860 //#endif //DESKTOP_VERSION
1861 setUpdatesEnabled( TRUE );
1862 repaint( TRUE );
1863}
1864
1865void KToolBar::toolBarPosChanged( QToolBar *tb )
1866{
1867 if ( tb != this )
1868 return;
1869//US if ( d->oldPos == DockMinimized )
1870 if ( d->oldPos == QMainWindow::Minimized )
1871 rebuildLayout();
1872 d->oldPos = (QMainWindow::ToolBarDock)barPos();
1873/*US
1874 if ( mainWindow() && mainWindow()->inherits( "KMainWindow" ) )
1875 static_cast<KMainWindow *>(mainWindow())->setSettingsDirty();
1876*/
1877}
1878
1879/*US
1880void KToolBar::loadState( const QDomElement &element )
1881{
1882 //kdDebug(220) << "KToolBar::loadState " << this << endl;
1883 if ( !mainWindow() )
1884 return;
1885
1886 {
1887 QCString text = element.namedItem( "text" ).toElement().text().utf8();
1888 if ( text.isEmpty() )
1889 text = element.namedItem( "Text" ).toElement().text().utf8();
1890 if ( !text.isEmpty() )
1891 setText( i18n( text ) );
1892 }
1893
1894 {
1895 QCString attrFullWidth = element.attribute( "fullWidth" ).lower().latin1();
1896 if ( !attrFullWidth.isEmpty() )
1897 setFullSize( attrFullWidth == "true" );
1898 }
1899
1900 Dock dock = DockTop;
1901 {
1902 QCString attrPosition = element.attribute( "position" ).lower().latin1();
1903 //kdDebug(220) << "KToolBar::loadState attrPosition=" << attrPosition << endl;
1904 if ( !attrPosition.isEmpty() ) {
1905 if ( attrPosition == "top" )
1906 dock = DockTop;
1907 else if ( attrPosition == "left" )
1908 dock = DockLeft;
1909 else if ( attrPosition == "right" )
1910 dock = DockRight;
1911 else if ( attrPosition == "bottom" )
1912 dock = DockBottom;
1913 else if ( attrPosition == "floating" )
1914 dock = DockTornOff;
1915 else if ( attrPosition == "flat" )
1916 dock = DockMinimized;
1917 }
1918 }
1919
1920 {
1921 QCString attrIconText = element.attribute( "iconText" ).lower().latin1();
1922 if ( !attrIconText.isEmpty() ) {
1923 //kdDebug(220) << "KToolBar::loadState attrIconText=" << attrIconText << endl;
1924 if ( attrIconText == "icontextright" )
1925 setIconText( KToolBar::IconTextRight );
1926 else if ( attrIconText == "textonly" )
1927 setIconText( KToolBar::TextOnly );
1928 else if ( attrIconText == "icontextbottom" )
1929 setIconText( KToolBar::IconTextBottom );
1930 else if ( attrIconText == "icononly" )
1931 setIconText( KToolBar::IconOnly );
1932 } else
1933 // Use global setting
1934 setIconText( iconTextSetting() );
1935 }
1936
1937 {
1938 QString attrIconSize = element.attribute( "iconSize" ).lower();
1939 if ( !attrIconSize.isEmpty() )
1940 d->IconSizeDefault = attrIconSize.toInt();
1941 setIconSize( d->IconSizeDefault );
1942 }
1943
1944 {
1945 QString attrIndex = element.attribute( "index" ).lower();
1946 if ( !attrIndex.isEmpty() )
1947 d->IndexDefault = attrIndex.toInt();
1948 }
1949
1950 {
1951 QString attrOffset = element.attribute( "offset" ).lower();
1952 if ( !attrOffset.isEmpty() )
1953 d->OffsetDefault = attrOffset.toInt();
1954 }
1955
1956 {
1957 QString attrNewLine = element.attribute( "newline" ).lower();
1958 if ( !attrNewLine.isEmpty() )
1959 d->NewLineDefault = attrNewLine == "true";
1960 }
1961
1962 {
1963 QString attrHidden = element.attribute( "hidden" ).lower();
1964 if ( !attrHidden.isEmpty() )
1965 d->HiddenDefault = attrHidden == "true";
1966 }
1967
1968 d->toolBarInfo = KToolBarPrivate::ToolBarInfo( dock, d->IndexDefault, d->NewLineDefault, d->OffsetDefault );
1969 mainWindow()->addDockWindow( this, dock, d->NewLineDefault );
1970//US mainWindow()->moveDockWindow( this, dock, d->NewLineDefault, d->IndexDefault, d->OffsetDefault );
1971 mainWindow()->moveToolBar( this, dock, d->NewLineDefault, d->IndexDefault, d->OffsetDefault );
1972
1973 // Apply the highlight button setting
1974 d->m_highlight = highlightSetting();
1975
1976 // Apply transparent-toolbar-moving setting (ok, this is global to the mainwindow,
1977 // but we do it only if there are toolbars...)
1978 if ( transparentSetting() != !mainWindow()->opaqueMoving() )
1979 mainWindow()->setOpaqueMoving( !transparentSetting() );
1980
1981 if ( d->HiddenDefault )
1982 hide();
1983 else
1984 show();
1985
1986 getAttributes( d->PositionDefault, d->IconTextDefault, d->IndexDefault );
1987}
1988*/
1989
1990void KToolBar::getAttributes( QString &position, QString &icontext, int &index )
1991{
1992 // get all of the stuff to save
1993 switch ( barPos() ) {
1994 case KToolBar::Flat:
1995 position = "Flat";
1996 break;
1997 case KToolBar::Bottom:
1998 position = "Bottom";
1999 break;
2000 case KToolBar::Left:
2001 position = "Left";
2002 break;
2003 case KToolBar::Right:
2004 position = "Right";
2005 break;
2006 case KToolBar::Floating:
2007 position = "Floating";
2008 break;
2009 case KToolBar::Top:
2010 default:
2011 position = "Top";
2012 break;
2013 }
2014
2015 if ( mainWindow() ) {
2016 QMainWindow::ToolBarDock dock;
2017 bool newLine;
2018 int offset;
2019 mainWindow()->getLocation( this, dock, index, newLine, offset );
2020 }
2021
2022 switch (d->m_iconText) {
2023 case KToolBar::IconTextRight:
2024 icontext = "IconTextRight";
2025 break;
2026 case KToolBar::IconTextBottom:
2027 icontext = "IconTextBottom";
2028 break;
2029 case KToolBar::TextOnly:
2030 icontext = "TextOnly";
2031 break;
2032 case KToolBar::IconOnly:
2033 default:
2034 icontext = "IconOnly";
2035 break;
2036 }
2037}
2038/*US
2039void KToolBar::saveState( QDomElement &current )
2040{
2041 QString position, icontext;
2042 int index = -1;
2043 getAttributes( position, icontext, index );
2044
2045 current.setAttribute( "noMerge", "1" );
2046 current.setAttribute( "position", position );
2047 current.setAttribute( "iconText", icontext );
2048 current.setAttribute( "index", index );
2049 current.setAttribute( "offset", offset() );
2050 current.setAttribute( "newline", newLine() );
2051 if ( isHidden() )
2052 current.setAttribute( "hidden", "true" );
2053 d->modified = true;
2054}
2055*/
2056
2057void KToolBar::positionYourself( bool force )
2058{
2059 if (force)
2060 d->positioned = false;
2061
2062 if ( d->positioned || !mainWindow() )
2063 {
2064 //kdDebug(220) << "KToolBar::positionYourself d->positioned=true ALREADY DONE" << endl;
2065 return;
2066 }
2067 // we can't test for ForceHide after moveDockWindow because QDockArea
2068 // does a reparent() with showIt == true
2069 bool doHide = isHidden();
2070 //kdDebug(220) << "positionYourself " << name() << " dock=" << d->toolBarInfo.dock << " newLine=" << d->toolBarInfo.newline << " offset=" << d->toolBarInfo.offset << endl;
2071/*US mainWindow()->moveDockWindow( this, d->toolBarInfo.dock,
2072 d->toolBarInfo.newline,
2073 d->toolBarInfo.index,
2074 d->toolBarInfo.offset );
2075*/
2076 mainWindow()->moveToolBar( this, d->toolBarInfo.dock, d->NewLineDefault, d->IndexDefault, d->OffsetDefault );
2077
2078 if ( doHide )
2079 hide();
2080 // This method can only have an effect once - unless force is set
2081 d->positioned = TRUE;
2082}
2083
2084//US KPopupMenu *KToolBar::contextMenu()
2085QPopupMenu *KToolBar::contextMenu()
2086{
2087 if ( context )
2088 return context;
2089
2090 // Construct our context popup menu. Name it qt_dockwidget_internal so it
2091 // won't be deleted by QToolBar::clear().
2092//US context = new KPopupMenu( this, "qt_dockwidget_internal" );
2093 context = new QPopupMenu( this, "qt_dockwidget_internal" );
2094//US context->insertTitle(i18n("Toolbar Menu"));
2095
2096//US KPopupMenu *orient = new KPopupMenu( context, "orient" );
2097 QPopupMenu *orient = new QPopupMenu( context, "orient" );
2098 orient->insertItem( i18n("toolbar position string","Top"), CONTEXT_TOP );
2099 orient->insertItem( i18n("toolbar position string","Left"), CONTEXT_LEFT );
2100 orient->insertItem( i18n("toolbar position string","Right"), CONTEXT_RIGHT );
2101 orient->insertItem( i18n("toolbar position string","Bottom"), CONTEXT_BOTTOM );
2102 orient->insertSeparator(-1);
2103 //orient->insertItem( i18n("toolbar position string","Floating"), CONTEXT_FLOAT );
2104 orient->insertItem( i18n("min toolbar", "Flat"), CONTEXT_FLAT );
2105
2106//US KPopupMenu *mode = new KPopupMenu( context, "mode" );
2107 QPopupMenu *mode = new QPopupMenu( context, "mode" );
2108 mode->insertItem( i18n("Icons Only"), CONTEXT_ICONS );
2109 mode->insertItem( i18n("Text Only"), CONTEXT_TEXT );
2110 mode->insertItem( i18n("Text Alongside Icons"), CONTEXT_TEXTRIGHT );
2111 mode->insertItem( i18n("Text Under Icons"), CONTEXT_TEXTUNDER );
2112
2113//US KPopupMenu *size = new KPopupMenu( context, "size" );
2114 QPopupMenu *size = new QPopupMenu( context, "size" );
2115 size->insertItem( i18n("Default"), CONTEXT_ICONSIZES );
2116 // Query the current theme for available sizes
2117 QValueList<int> avSizes;
2118/*US
2119 KIconTheme *theme = KGlobal::instance()->iconLoader()->theme();
2120 if (!::qstrcmp(QObject::name(), "mainToolBar"))
2121 avSizes = theme->querySizes( KIcon::MainToolbar);
2122 else
2123 avSizes = theme->querySizes( KIcon::Toolbar);
2124*/
2125 avSizes << 16;
2126 avSizes << 32;
2127
2128 d->iconSizes = avSizes;
2129
2130 QValueList<int>::Iterator it;
2131 for (it=avSizes.begin(); it!=avSizes.end(); it++) {
2132 QString text;
2133 if ( *it < 19 )
2134 text = i18n("Small (%1x%2)").arg(*it).arg(*it);
2135 else if (*it < 25)
2136 text = i18n("Medium (%1x%2)").arg(*it).arg(*it);
2137 else
2138 text = i18n("Large (%1x%2)").arg(*it).arg(*it);
2139 //we use the size as an id, with an offset
2140 size->insertItem( text, CONTEXT_ICONSIZES + *it );
2141 }
2142
2143 context->insertItem( i18n("Orientation"), orient );
2144 orient->setItemChecked(CONTEXT_TOP, true);
2145 context->insertItem( i18n("Text Position"), mode );
2146 context->setItemChecked(CONTEXT_ICONS, true);
2147 context->insertItem( i18n("Icon Size"), size );
2148
2149/*US
2150 if (mainWindow()->inherits("KMainWindow"))
2151 {
2152 if ( (static_cast<KMainWindow*>(mainWindow())->toolBarMenuAction()) &&
2153 (static_cast<KMainWindow*>(mainWindow())->hasMenuBar()) )
2154
2155 (static_cast<KMainWindow*>(mainWindow()))->toolBarMenuAction()->plug(context);
2156 }
2157*/
2158
2159 connect( context, SIGNAL( aboutToShow() ), this, SLOT( slotContextAboutToShow() ) );
2160 return context;
2161}
2162
2163void KToolBar::slotContextAboutToShow()
2164{
2165 if (!d->m_configurePlugged)
2166 {
2167 // try to find "configure toolbars" action
2168
2169 KXMLGUIClient *xmlGuiClient = d->m_xmlguiClient;
2170 if ( !xmlGuiClient && mainWindow() && mainWindow()->inherits( "KMainWindow" ) )
2171 xmlGuiClient = (KXMLGUIClient *)mainWindow();
2172 if ( xmlGuiClient )
2173 {
2174 KAction *configureAction = xmlGuiClient->actionCollection()->action(KStdAction::stdName(KStdAction::ConfigureToolbars));
2175 if ( configureAction )
2176 {
2177 configureAction->plug(context);
2178 d->m_configurePlugged = true;
2179 }
2180 }
2181 }
2182
2183 for(int i = CONTEXT_ICONS; i <= CONTEXT_TEXTUNDER; ++i)
2184 context->setItemChecked(i, false);
2185
2186 switch( d->m_iconText )
2187 {
2188 case IconOnly:
2189 default:
2190 context->setItemChecked(CONTEXT_ICONS, true);
2191 break;
2192 case IconTextRight:
2193 context->setItemChecked(CONTEXT_TEXTRIGHT, true);
2194 break;
2195 case TextOnly:
2196 context->setItemChecked(CONTEXT_TEXT, true);
2197 break;
2198 case IconTextBottom:
2199 context->setItemChecked(CONTEXT_TEXTUNDER, true);
2200 break;
2201 }
2202
2203 QValueList<int>::ConstIterator iIt = d->iconSizes.begin();
2204 QValueList<int>::ConstIterator iEnd = d->iconSizes.end();
2205 for (; iIt != iEnd; ++iIt )
2206 context->setItemChecked( CONTEXT_ICONSIZES + *iIt, false );
2207
2208 context->setItemChecked( CONTEXT_ICONSIZES, false );
2209
2210 context->setItemChecked( CONTEXT_ICONSIZES + d->m_iconSize, true );
2211
2212 for ( int i = CONTEXT_TOP; i <= CONTEXT_FLAT; ++i )
2213 context->setItemChecked( i, false );
2214
2215 switch ( barPos() )
2216 {
2217 case KToolBar::Flat:
2218 context->setItemChecked( CONTEXT_FLAT, true );
2219 break;
2220 case KToolBar::Bottom:
2221 context->setItemChecked( CONTEXT_BOTTOM, true );
2222 break;
2223 case KToolBar::Left:
2224 context->setItemChecked( CONTEXT_LEFT, true );
2225 break;
2226 case KToolBar::Right:
2227 context->setItemChecked( CONTEXT_RIGHT, true );
2228 break;
2229 case KToolBar::Floating:
2230 context->setItemChecked( CONTEXT_FLOAT, true );
2231 break;
2232 case KToolBar::Top:
2233 context->setItemChecked( CONTEXT_TOP, true );
2234 break;
2235 default: break;
2236 }
2237}
2238
2239void KToolBar::widgetDestroyed()
2240{
2241 removeWidgetInternal( (QWidget*)sender() );
2242}
2243
2244void KToolBar::removeWidgetInternal( QWidget * w )
2245{
2246 if ( inshutdownprocess )
2247 return;
2248 widgets.removeRef( w );
2249 QMap< QWidget*, int >::Iterator it = widget2id.find( w );
2250 if ( it == widget2id.end() )
2251 return;
2252 id2widget.remove( *it );
2253 widget2id.remove( it );
2254}
2255
2256void KToolBar::virtual_hook( int, void* )
2257{ /*BASE::virtual_hook( id, data );*/ }
2258
2259//US #include "ktoolbar.moc"
2260
diff --git a/microkde/kdeui/ktoolbar.h b/microkde/kdeui/ktoolbar.h
new file mode 100644
index 0000000..2c061b5
--- a/dev/null
+++ b/microkde/kdeui/ktoolbar.h
@@ -0,0 +1,1107 @@
1/* This file is part of the KDE libraries
2 Copyright (C) 2000 Reginald Stadlbauer (reggie@kde.org)
3 (C) 1997, 1998 Stephan Kulow (coolo@kde.org)
4 (C) 1997, 1998 Sven Radej (radej@kde.org)
5 (C) 1997, 1998 Mark Donohoe (donohoe@kde.org)
6 (C) 1997, 1998 Matthias Ettrich (ettrich@kde.org)
7 (C) 1999, 2000 Kurt Granroth (granroth@kde.org)
8
9 This library is free software; you can redistribute it and/or
10 modify it under the terms of the GNU Library General Public
11 License version 2 as published by the Free Software Foundation.
12
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Library General Public License for more details.
17
18 You should have received a copy of the GNU Library General Public License
19 along with this library; see the file COPYING.LIB. If not, write to
20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA.
22 */
23
24#ifndef KTOOLBAR_H
25#define KTOOLBAR_H
26
27#ifndef DESKTOP_VERSION
28#define private public
29#include <qtoolbar.h>
30#undef private
31#include <qpe/qpetoolbar.h>
32#else
33#include <qtoolbar.h>
34#endif
35
36
37#include <qmainwindow.h>
38#include <qcombobox.h>
39#include <qmap.h>
40#include <qptrlist.h>
41#include <kglobal.h>
42#include <qguardedptr.h>
43#include <qframe.h>
44#include <qiconset.h>
45
46class QDomElement;
47class QSize;
48class QPixmap;
49class QPopupMenu;
50class QStringList;
51class QDomDocument;
52class QTimer;
53
54class KLineEdit;
55class KToolBar;
56class KToolBarButton;
57class KToolBoxManager;
58//US class KAnimWidget;
59//US class KPopupMenu;
60//US class KInstance;
61class KComboBox;
62class KXMLGUIClient;
63
64class KToolBarPrivate;
65
66class KToolBarSeparator : public QFrame
67{
68 Q_OBJECT
69public:
70 KToolBarSeparator( Orientation, bool l, QToolBar *parent, const char* name=0 );
71
72 QSize sizeHint() const;
73 Orientation orientation() const { return orient; }
74 QSizePolicy sizePolicy() const;
75 bool showLine() const { return line; }
76public slots:
77 void setOrientation( Orientation );
78protected:
79 void styleChange( QStyle& );
80private:
81 Orientation orient;
82 bool line;
83};
84
85
86 /**
87 * A KDE-style toolbar.
88 *
89 * KToolBar can be dragged around in and between different docks.
90 *
91 * A KToolBar can contain all sorts of widgets.
92 *
93 * KToolBar can be used as a standalone widget, but @ref KMainWindow
94 * provides easy factories and management of one or more toolbars.
95 * Once you have a KToolBar object, you can insert items into it with the
96 * insert... methods, or remove them with the @ref removeItem() method. This
97 * can be done at any time; the toolbar will be automatically updated.
98 * There are also many methods to set per-child properties like alignment
99 * and toggle behaviour.
100 *
101 * KToolBar uses a global config group to load toolbar settings on
102 * construction. It will reread this config group on a
103 * @ref KApplication::appearanceChanged() signal.
104 *
105 * @short Floatable toolbar with auto resize.
106 * @version $Id$
107 * @author Reginald Stadlbauer <reggie@kde.org>, Stephan Kulow <coolo@kde.org>, Sven Radej <radej@kde.org>.
108 */
109
110// strange things are happening ... so I have to use strange define methods ...
111// porting KToolBar back to Qt2 really needs some strange hacks
112
113#ifndef DESKTOP_VERSION
114#define QToolBar QPEToolBar
115#endif
116
117 class KToolBar : public QToolBar
118{
119 Q_OBJECT
120
121
122 Q_ENUMS( IconText BarPosition )
123
124 Q_PROPERTY( IconText iconText READ iconText WRITE setIconText )
125 Q_PROPERTY( BarPosition barPos READ barPos WRITE setBarPos )
126 Q_PROPERTY( bool fullSize READ fullSize WRITE setFullSize )
127 Q_PROPERTY( int iconSize READ iconSize WRITE setIconSize )
128 Q_PROPERTY( QString text READ text WRITE setText )
129#ifndef DESKTOP_VERSION
130#undef QToolBar
131#endif
132public:
133 enum IconText{IconOnly = 0, IconTextRight, TextOnly, IconTextBottom};
134 /**
135 * The state of the status bar.
136 * @deprecated
137 **/
138 enum BarStatus{Toggle, Show, Hide};
139 /**
140 * Possible bar positions.
141 **/
142 enum BarPosition{ Unmanaged, Floating, Top, Bottom, Right, Left, Flat};
143
144 /**
145 * Constructor.
146 * This constructor is used by the XML-GUI. If you use it, you need
147 * to call QMainWindow::addToolBar to specify the position of the toolbar.
148 * So it's simpler to use the other constructor.
149 *
150 * The toolbar will read in various global config settings for
151 * things like icon size and text position, etc. However, some of
152 * the settings will be honored only if @ref #_honor_mode is set to
153 * true. All other toolbars will be IconOnly and use Medium icons.
154 *
155 * @param parent The standard toolbar parent (usually a
156 * @ref KMainWindow)
157 * @param name The standard internal name
158 * @param honor_style If true, then global settings for IconSize and IconText will be honored
159 * @param readConfig whether to apply the configuration (global and application-specific)
160 */
161 KToolBar( QWidget *parent, const char *name = 0, bool honor_style = FALSE, bool readConfig = TRUE );
162
163 /**
164 * Constructor for non-XML-GUI applications.
165 *
166 * The toolbar will read in various global config settings for
167 * things like icon size and text position, etc. However, some of
168 * the settings will be honored only if @ref #_honor_mode is set to
169 * true. All other toolbars will be IconOnly and use Medium icons.
170 *
171 * @param parentWindow The window that should be the parent of this toolbar
172 * @param dock The position of the toolbar. Usually QMainWindow::Top.
173 * @param newLine If true, start a new line in the dock for this toolbar.
174 * @param name The standard internal name
175 * @param honor_style If true, then global settings for IconSize and IconText will be honored
176 * @param readConfig whether to apply the configuration (global and application-specific)
177 */
178 KToolBar( QMainWindow *parentWindow, QMainWindow::ToolBarDock dock /*= QMainWindow::Top*/, bool newLine = false,
179 const char *name = 0, bool honor_style = FALSE, bool readConfig = TRUE );
180
181 /**
182 * Constructor for non-XML-GUI applications.
183 *
184 * The toolbar will read in various global config settings for
185 * things like icon size and text position, etc. However, some of
186 * the settings will be honored only if @ref #_honor_mode is set to
187 * true. All other toolbars will be IconOnly and use Medium icons.
188 *
189 * @param parentWindow The window that should be the parent of this toolbar
190 * @param dock Another widget than the mainwindow to dock toolbar to.
191 * @param newLine If true, start a new line in the dock for this toolbar.
192 * @param name The standard internal name
193 * @param honor_style If true, then global settings for IconSize and IconText will be honored
194 * @param readConfig whether to apply the configuration (global and application-specific)
195 */
196 KToolBar( QMainWindow *parentWindow, QWidget *dock, bool newLine = false,
197 const char *name = 0, bool honor_style = FALSE, bool readConfig = TRUE );
198
199 virtual ~KToolBar();
200
201 /**
202 * Insert a button (a @ref KToolBarButton) with a pixmap. The
203 * pixmap is loaded by the button itself based on the global icon
204 * settings.
205 *
206 * You should connect to one or more signals in KToolBar:
207 * @ref clicked() , @ref pressed() , @ref released() , or
208 * @ref highlighted() and if the button is a toggle button
209 * (@ref setToggle() ) @ref toggled() . Those signals have @p id
210 * of a button that caused the signal. If you want to bind a popup
211 * to button, see @ref setButton().
212 *
213 * @param icon The name of the icon to use as the active pixmap
214 * @param id The id of this button
215 * @param enabled Enable or disable the button at startup
216 * @param text The tooltip or toolbar text (depending on state)
217 * @param index The position of the button. (-1 = at end).
218 *
219 * @return The item index.
220 */
221 int insertButton(const QString& icon, int id, bool enabled = true,
222 const QString& text = QString::null, int index=-1/*US ,
223 KInstance *_instance = KGlobal::instance()*/);
224
225 /**
226 * This is the same as above, but with specified signals and
227 * slots to which this button will be connected.
228 *
229 * You can add more signals with @ref addConnection().
230 *
231 * @param icon The name of the icon to use as the active pixmap
232 * @param id The id of this button
233 * @param signal The signal to connect to
234 * @param receiver The slot's parent
235 * @param enabled Enable or disable the button at startup
236 * @param text The tooltip or toolbar text (depending on state)
237 * @param index The position of the button. (-1 = at end).
238 *
239 * @return The item index.
240 */
241 int insertButton(const QString& icon, int id, const char *signal,
242 const QObject *receiver, const char *slot,
243 bool enabled = true, const QString& text = QString::null,
244 int index=-1/*US, KInstance *_instance = KGlobal::instance()*/ );
245
246 /**
247 * Inserts a button (a @ref KToolBarButton) with the specified
248 * pixmap. This pixmap will be used as the "active" one and the
249 * disabled and default ones will be autogenerated.
250 *
251 * It is recommended that you use the insertButton function that
252 * allows you to specify the icon name rather then the pixmap
253 * itself. Specifying the icon name is much more flexible.
254 *
255 * You should connect to one or more signals in KToolBar:
256 * @ref clicked() , @ref pressed() , @ref released() , or
257 * @ref highlighted() and if the button is a toggle button
258 * (@ref setToggle() ) @ref toggled() . Those signals have @p id
259 * of a button that caused the signal. If you want to bind a popup
260 * to button, see @ref setButton().
261 *
262 * @param pixmap The active pixmap
263 * @param id The id of this button
264 * @param enabled Enable or disable the button at startup
265 * @param text The tooltip or toolbar text (depending on state)
266 * @param index The position of the button. (-1 = at end).
267 *
268 * @return The item index.
269 */
270 int insertButton(const QPixmap& pixmap, int id, bool enabled = true,
271 const QString& text = QString::null, int index=-1 );
272
273 /**
274 * This is the same as above, but with specified signals and
275 * slots to which this button will be connected.
276 *
277 * You can add more signals with @ref addConnection().
278 *
279 * @param icon The name of the icon to use as the active pixmap
280 * @param id The id of this button
281 * @param signal The signal to connect to
282 * @param receiver The slot's parent
283 * @param enabled Enable or disable the button at startup
284 * @param text The tooltip or toolbar text (depending on state)
285 * @param index The position of the button. (-1 = at end).
286 *
287 * @return The item index.
288 */
289 int insertButton(const QPixmap& pixmap, int id, const char *signal,
290 const QObject *receiver, const char *slot,
291 bool enabled = true, const QString& text = QString::null,
292 int index=-1 );
293
294 /**
295 * Inserts a button with popupmenu.
296 *
297 * Button will have small
298 * triangle. You have to connect to popup's signals. The
299 * signals @ref KButton::pressed(), @ref KButton::released(),
300 * @ref KButton::clicked() or @ref KButton::doubleClicked() are @p not
301 * emmited by
302 * this button (see @ref setDelayedPopup() for that).
303 * You can add custom popups which inherit @ref QPopupMenu to get popups
304 * with tables, drawings etc. Just don't fiddle with events there.
305 */
306 int insertButton(const QString& icon, int id, QPopupMenu *popup,
307 bool enabled, const QString&_text, int index=-1);
308
309 /**
310 * Inserts a button with popupmenu.
311 *
312 * Button will have small
313 * triangle. You have to connect to popup's signals. The
314 * signals @ref KButton::pressed(), @ref KButton::released(),
315 * @ref KButton::clicked() or @ref KButton::doubleClicked() are @p not
316 * emmited by
317 * this button (see @ref setDelayedPopup() for that).
318 * You can add custom popups which inherit @ref QPopupMenu to get popups
319 * with tables, drawings etc. Just don't fiddle with events there.
320 */
321 int insertButton(const QPixmap& pixmap, int id, QPopupMenu *popup,
322 bool enabled, const QString&_text, int index=-1);
323
324 /**
325 * Inserts a @ref KLineEdit. You have to specify signals and slots to
326 * which KLineEdit will be connected. KLineEdit has all slots QLineEdit
327 * has, plus signals @ref KLineEdit::completion and @ref KLineEdit::textRotation
328 * KLineEdit can be set to autoresize itself to full free width
329 * in toolbar, that is to last right aligned item. For that,
330 * toolbar must be set to full width (which it is by default).
331 * @see setFullWidth()
332 * @see setItemAutoSized()
333 * @see KLineEdit
334 * @return Item index.
335 */
336 int insertLined (const QString& text, int id,
337 const char *signal,
338 const QObject *receiver, const char *slot,
339 bool enabled = true,
340 const QString& toolTipText = QString::null,
341 int size = 70, int index =-1);
342
343 /**
344 * Inserts a @ref KComboBox with list.
345 *
346 * Can be writable, but cannot contain
347 * pixmaps. By default inserting policy is AtBottom, i.e. typed items
348 * are placed at the bottom of the list. Can be autosized. If the size
349 * argument is specified as -1, the width of the combobox is automatically
350 * computed.
351 *
352 * @see setFullWidth()
353 * @see setItemAutoSized()
354 * @see KComboBox
355 * @return Item index.
356 */
357 int insertCombo (const QStringList &list, int id, bool writable,
358 const char *signal, const QObject *receiver,
359 const char *slot, bool enabled=true,
360 const QString& tooltiptext=QString::null,
361 int size=70, int index=-1,
362 QComboBox::Policy policy = QComboBox::AtBottom);
363
364 /**
365 * Insert a @ref KComboBox with text.
366 *
367 * The rest is the same as above.
368 * @see setItemAutoSized()
369 *
370 * @see KComboBox
371 * @return Item index.
372 */
373 int insertCombo (const QString& text, int id, bool writable,
374 const char *signal, QObject *recevier,
375 const char *slot, bool enabled=true,
376 const QString& tooltiptext=QString::null,
377 int size=70, int index=-1,
378 QComboBox::Policy policy = QComboBox::AtBottom);
379
380 /**
381 * Inserts a separator into the toolbar with the given id.
382 * Returns the separator's index
383 */
384 int insertSeparator( int index = -1, int id = -1 );
385
386 /**
387 * Inserts a line separator into the toolbar with the given id.
388 * Returns the separator's index
389 */
390 int insertLineSeparator( int index = -1, int id = -1 );
391
392 /**
393 * Inserts a user-defined widget. The widget @p must have this
394 * toolbar as its parent.
395 *
396 * Widget must have a QWidget for base class. Widget can be
397 * autosized to full width. If you forget about it, you can get a
398 * pointer to this widget with @ref getWidget().
399 * @see setItemAutoSized()
400 * @return Item index.
401 */
402 int insertWidget(int id, int width, QWidget *_widget, int index=-1);
403
404 /**
405 * Inserts an animated widget. A @ref KAnimWidget will be created
406 * internally using the icon name you provide.
407 * This will emit a signal (clicked()) whenever the
408 * animation widget is clicked.
409 *
410 * @see animatedWidget()
411 *
412 * @param id The id for this toolbar item
413 * @param receiver The parent of your slot
414 * @param slot The slot to receive the clicked() signal
415 * @param icons The name of the animation icon group to use
416 * @param index The item index
417 *
418 * @return The item index
419 */
420/*US
421 int insertAnimatedWidget(int id, QObject *receiver, const char *slot,
422 const QString& icons, int index = -1);
423*/
424 /**
425 * This will return a pointer to the given animated widget, if it
426 * exists.
427 *
428 * @see insertAnimatedWidget
429 *
430 * @param id The id for the widget you want to get a pointer to
431 *
432 * @return A pointer to the current animated widget or 0L
433 */
434//US KAnimWidget *animatedWidget( int id );
435
436 /**
437 * Adds connections to items.
438 *
439 * It is important that you
440 * know the @p id of particular item. Nothing happens if you forget @p id.
441 */
442 void addConnection (int id, const char *signal,
443 const QObject *receiver, const char *slot);
444 /**
445 * Enables/disables item.
446 */
447 void setItemEnabled( int id, bool enabled );
448
449 /**
450 * Sets the icon for a button.
451 *
452 * Can be used while button is visible.
453 */
454 void setButtonIcon( int id, const QString& _icon );
455
456 /**
457 * Sets button pixmap.
458 *
459 * Can be used while button is visible.
460 */
461 void setButtonPixmap( int id, const QPixmap& _pixmap );
462
463 /**
464 * Sets a button icon from a QIconSet.
465 *
466 * Can be used while button is visible.
467 */
468 void setButtonIconSet( int id, const QIconSet& iconset );
469
470 /**
471 * Sets a delayed popup for a button.
472 *
473 * Delayed popup is what you see in
474 * Netscape Navigator's Previous and Next buttons: If you click them you
475 * go back
476 * or forth. If you press them long enough, you get a history-menu.
477 * This is exactly what we do here.
478 *
479 * You will insert normal a button with connection (or use signals from
480 * toolbar):
481 * <pre>
482 * bar->insertButton(icon, id, SIGNAL(clicked ()), this,
483 * SLOT (slotClick()), true, "click or wait for popup");
484 * </pre> And then add a delayed popup:
485 * <pre>
486 * bar->setDelayedPopup (id, historyPopup); </pre>
487 *
488 * Don't add delayed popups to buttons which have normal popups.
489 *
490 * You may add popups which are derived from @ref QPopupMenu. You may
491 * add popups that are already in the menu bar or are submenus of
492 * other popups.
493 */
494 void setDelayedPopup (int id , QPopupMenu *_popup, bool toggle = false);
495
496 /**
497 * Turns a button into an autorepeat button.
498 *
499 * Toggle buttons, buttons with menus, or
500 * buttons with delayed menus cannot be made into autorepeat buttons.
501 * Moreover, you can and will receive
502 * only the signal clicked(), but not pressed() or released().
503 * When the user presses this button, you will receive the signal clicked(),
504 * and if the button is still pressed after some time,
505 * you will receive more clicked() signals separated by regular
506 * intervals. Since this uses @ref QButton::setAutoRepeat() ,
507 * I can't quantify 'some'.
508 */
509 void setAutoRepeat (int id, bool flag=true);
510
511
512 /**
513 * Turns button into a toggle button if @p flag is true.
514 */
515 void setToggle (int id, bool flag = true);
516
517 /**
518 * Toggles a togglebutton.
519 *
520 * If the button is a toggle button (see @ref setToggle())
521 * the button state will be toggled. This will also cause the toolbar to
522 * emit the signal @ref KButton::toggled() with parameter @p id. You must connect to
523 * this signal, or use @ref addConnection() to connect directly to the
524 * button signal @ref KButton::toggled().
525 */
526 void toggleButton (int id);
527
528 /**
529 * Sets a toggle button state.
530 *
531 * If the button is a toggle button (see @ref setToggle())
532 * this will set its state flag. This will also emit the signal
533 * @ref KButton::toggled().
534 *
535 * @see setToggle()
536 */
537 void setButton (int id, bool flag);
538
539 /**
540 * @return @p true if button is on, @p false if button is off or if the
541 * button is not a toggle button.
542 * @see setToggle()
543 */
544 bool isButtonOn (int id) const;
545
546 /**
547 * Sets the text of a line editor.
548 *
549 * Cursor is set at end of text.
550 */
551 void setLinedText (int id, const QString& text);
552
553 /**
554 * Returns a line editor text.
555 */
556 QString getLinedText (int id) const;
557
558 /**
559 * Inserts @p text in combobox @p id at position @p index.
560 */
561 void insertComboItem (int id, const QString& text, int index);
562
563 /**
564 * Inserts @p list in combobox @p id at position @p index.
565 */
566 void insertComboList (int id, const QStringList &list, int index);
567
568 /**
569 * Removes item @p index from combobox @p id.
570 */
571 void removeComboItem (int id, int index);
572
573 /**
574 * Sets item @p index to be current item in combobox @p id.
575 */
576 void setCurrentComboItem (int id, int index);
577
578 /**
579 * Changes item @p index in combobox @p id to text.
580 *
581 * @p index = -1 refers current item (one displayed in the button).
582 */
583 void changeComboItem (int id, const QString& text, int index=-1);
584
585 /**
586 * Clears the combobox @p id.
587 *
588 * Does not delete it or hide it.
589 */
590 void clearCombo (int id);
591
592 /**
593 * Returns text of item @p index from combobox @p id.
594 *
595 * @p index = -1 refers to current item.
596 */
597
598 QString getComboItem (int id, int index=-1) const;
599
600 /**
601 * Returns a pointer to the combobox.
602 *
603 * Example:
604 * <pre>
605 * KComboBox *combo = toolbar->getCombo(combo_id);
606 * </pre>
607 * That way you can get access to other public methods
608 * that @ref KComboBox provides.
609 */
610 KComboBox * getCombo(int id);
611
612 /**
613 * Returns a pointer to KToolBarLined.
614 *
615 * Example:
616 * <pre>
617 * KLineEdit * lined = toolbar->getKToolBarLined(lined_id);
618 * </pre>
619 * That way you can get access to other public methods
620 * that @ref KLineEdit provides. @ref KLineEdit is the same thing
621 * as @ref QLineEdit plus completion signals.
622 */
623 KLineEdit * getLined (int id);
624
625 /**
626 * Returns a pointer to KToolBarButton.
627 *
628 * Example:
629 * <pre>
630 * KToolBarButton * button = toolbar->getButton(button_id);
631 * </pre>
632 * That way you can get access to other public methods
633 * that @ref KToolBarButton provides.
634 *
635 * Using this method is not recommended.
636 */
637 KToolBarButton * getButton (int id);
638
639 /**
640 * Align item to the right.
641 *
642 * This works only if toolbar is set to full width.
643 * @see setFullWidth()
644 */
645 void alignItemRight (int id, bool right = true);
646
647 /**
648 * Returns a pointer to an inserted widget.
649 *
650 * Wrong ids are not tested.
651 * You can do with this whatever you want,
652 * except change its height (hardcoded). If you change its width
653 * you will probably have to call QToolBar::updateRects(true)
654 * @see QWidget
655 * @see updateRects()
656 *
657 * KDE4: make this const!
658 */
659 QWidget *getWidget (int id);
660
661 /**
662 * Set item autosized.
663 *
664 * This works only if the toolbar is set to full width.
665 * Only @p one item can be autosized, and it has to be
666 * the last left-aligned item. Items that come after this must be right
667 * aligned. Items that can be right aligned are Lineds, Frames, Widgets and
668 * Combos. An autosized item will resize itself whenever the toolbar geometry
669 * changes to the last right-aligned item (or to end of toolbar if there
670 * are no right-aligned items.)
671 * @see setFullWidth()
672 * @see alignItemRight()
673 */
674 void setItemAutoSized (int id, bool yes = true);
675
676 /**
677 * Remove all items.
678 *
679 * The toolbar is redrawn after it.
680 */
681 void clear ();
682
683 /**
684 * Remove item @p id.
685 *
686 * Item is deleted. Toolbar is redrawn after it.
687 */
688 void removeItem (int id);
689
690 /**
691 * Remove item @p id.
692 *
693 * Item is deleted when toolbar is redrawn.
694 */
695 void removeItemDelayed (int id);
696
697 /**
698 * Hide item.
699 */
700 void hideItem (int id);
701
702 /**
703 * Show item.
704 */
705 void showItem (int id);
706
707 /**
708 * Returns the index of the given item.
709 *
710 * KDE4: make this const!
711 */
712 int itemIndex (int id);
713
714 /**
715 * Set toolbar to full parent size (default).
716 *
717 * In full size mode the bar
718 * extends over the parent's full width or height. If the mode is disabled
719 * the toolbar tries to take as much space as it needs without wrapping, but
720 * it does not exceed the parent box. You can force a certain width or
721 * height with @ref setMaxWidth() or @ref setMaxHeight().
722 *
723 * If you want to use right-aligned items or auto-sized items you must use
724 * full size mode.
725 */
726 void setFullSize(bool flag = true);
727
728 /**
729 * @return @p true if the full-size mode is enabled. Otherwise
730 * it returns @false.
731 */
732 bool fullSize() const;
733
734 /**
735 * @deprecated use setMovingEnabled(bool) instead.
736 * Enable or disable moving of toolbar.
737 */
738 void enableMoving(bool flag = true);
739
740 /**
741 * Set position of toolbar.
742 * @see BarPosition()
743 */
744 void setBarPos (BarPosition bpos);
745
746 /**
747 * Returns position of toolbar.
748 */
749 BarPosition barPos();
750
751 /**
752 * @deprecated
753 * Show, hide, or toggle toolbar.
754 *
755 * This method is provided for compatibility only,
756 * please use show() and/or hide() instead.
757 * @see BarStatus
758 */
759 bool enable(BarStatus stat);
760
761 /**
762 * @deprecated
763 * Use setMaximumHeight() instead.
764 */
765 void setMaxHeight (int h); // Set max height for vertical toolbars
766
767 /**
768 * @deprecated
769 * Use maximumHeight() instead.
770 * Returns the value that was set with @ref setMaxHeight().
771 */
772 int maxHeight();
773
774 /**
775 * @deprecated
776 * Use setMaximumWidth() instead.
777 * Set maximal width of horizontal (top or bottom) toolbar.
778 */
779 void setMaxWidth (int dw);
780
781 /**
782 * @deprecated
783 * Use maximumWidth() instead.
784 * Returns the value that was set with @ref setMaxWidth().
785 */
786 int maxWidth();
787
788 /**
789 * Set title for toolbar when it floats.
790 *
791 * Titles are however not (yet)
792 * visible. You can't change toolbar's title while it's floating.
793 */
794 void setTitle (const QString& _title);
795
796 /**
797 * @deprecated
798 * Use enableMoving() instead.
799 */
800 void enableFloating (bool arrrrrrgh);
801
802 /**
803 * Set the kind of painting for buttons.
804 *
805 * Choose from:
806 * @li IconOnly (only icons),
807 * @li IconTextRight (icon and text, text is left from icons),
808 * @li TextOnly (only text),
809 * @li IconTextBottom (icons and text, text is under icons).
810 * @see IconText
811 *
812 */
813 void setIconText(IconText it);
814 // Note: don't merge with the next one, it breaks Qt properties
815
816 /**
817 * Similar to @ref setIconText(IconText it) but allows you to
818 * disable or enable updating. If @p update is false, then the
819 * buttons will not be updated. This is useful only if you know
820 * that you will be forcing an update later.
821 */
822 void setIconText(IconText it, bool update);
823
824 /**
825 * @return The current text style for buttons.
826 */
827 IconText iconText() const;
828
829 /**
830 * Set the icon size to load. Usually you should not call
831 * this, the icon size is taken care of by KIconLoader
832 * and globally configured.
833 * By default, the toolbar will load icons of size 32 for main
834 * toolbars and 22 for other toolbars
835 * @see KIconLoader.
836 *
837 * @param size The size to use
838 */
839 void setIconSize(int size);
840 // Note: don't merge with the next one, it breaks Qt properties
841
842 /**
843 * Same as @ref setIconText(int size) but allows you
844 * to disable the toolbar update.
845 *
846 * @param size The size to use
847 * @param update If true, then the toolbar will be updated after
848 * this
849 */
850 void setIconSize(int size, bool update);
851
852 /**
853 * @return The current icon size for buttons.
854 */
855 int iconSize() const;
856
857 /**
858 * This allows you to enable or disable the context menu.
859 *
860 * @param enable If false, then the context menu will be disabled
861 */
862 void setEnableContextMenu(bool enable = true);
863
864 /**
865 * Returns whether or not the context menu is disabled
866 *
867 * @return The context menu state
868 */
869 bool contextMenuEnabled() const;
870
871 /**
872 * This will inform a toolbar button to ignore certain style
873 * changes. Specifically, it will ignore IconText (always IconOnly)
874 * and will not allow image effects to apply.
875 *
876 * @param id The button to exclude from styles
877 * @param no_style If true, then it is excluded (default: true).
878 */
879 void setItemNoStyle(int id, bool no_style = true);
880
881 void setFlat (bool flag);
882
883 /**
884 * @return the number of items in the toolbar
885 */
886 int count() const;
887
888 /**
889 * Instruct the toolbar to save it's current state to either the app
890 * config file or to the XML-GUI resource file (whichever has
891 * precedence).
892 */
893 void saveState();
894
895 /**
896 * Save the toolbar settings to group @p configGroup in @p config.
897 */
898 void saveSettings(KConfig *config, const QString &configGroup);
899
900 /**
901 * Read the toolbar settings from group @p configGroup in @p config
902 * and apply them.
903 */
904 void applySettings(KConfig *config, const QString &configGroup);
905
906 /**
907 * Tell the toolbar what XML-GUI resource file it should use to save
908 * it's state. The state of the toolbar (position, size, etc) is
909 * saved in KConfig files if the application does not use XML-GUI..
910 * but if the app does, then it's saved the XML file. This function
911 * allows this to happen.
912 *
913 * @param xmlfile The XML-GUI resource file to write to
914 * @param xml The DOM document for the XML-GUI building
915 */
916 // void setXML(const QString& xmlfile, const QDomDocument& xml);
917 /* @internal */
918 void setXMLGUIClient( KXMLGUIClient *client );
919
920 /**
921 * Assign a (translated) text to this toolbar. This is used
922 * for the tooltip on the handle, and when listing the toolbars.
923 */
924 void setText( const QString & txt );
925
926 /**
927 * @return the toolbar's text.
928 */
929 QString text() const;
930
931 void setStretchableWidget( QWidget *w );
932 QSizePolicy sizePolicy() const;
933 bool highlight() const;
934 QSize sizeHint() const;
935 QSize minimumSizeHint() const;
936 QSize minimumSize() const;
937
938 void hide();
939 void show();
940
941 void updateRects( bool = FALSE ) {}
942
943//US void loadState( const QDomElement &e );
944//US void saveState( QDomElement &e );
945
946 /**
947 * @internal
948 */
949 void positionYourself( bool force = false);
950
951signals:
952 /**
953 * Emitted when button @p id is clicked.
954 */
955 void clicked(int id);
956
957 /**
958 * Emitted when button @p id is double-clicked.
959 *
960 * Note: you will always
961 * recive two @ref clicked() , @ref pressed() and @ref released() signals.
962 * There is no way to avoid it - at least no easy way.
963 * If you need to resolve this all you can do is set up timers
964 * which wait for @ref QApplication::doubleClickInterval() to expire.
965 * If in that time you don't get this signal, you may belive that
966 * button was only clicked and not double-clicked.
967 * And please note that butons with popup menus do not emit this signal,
968 * but those with delayed popup do.
969 */
970 void doubleClicked (int id);
971
972 /**
973 * Emitted when button @p id is pressed.
974 */
975 void pressed(int);
976
977 /**
978 * Emits when button @p id is released.
979 */
980 void released(int);
981
982 /**
983 * Emitted when a toggle button changes state.
984 *
985 * Emitted also if you change state
986 * with @ref setButton() or @ref toggleButton()
987 * If you make a button normal again, with
988 * setToggle(false), this signal won't
989 * be emitted.
990 */
991 void toggled(int);
992
993 /**
994 * This signal is emitted when item id gets highlighted/unhighlighted
995 * (i.e when mouse enters/exits).
996 *
997 * Note that this signal is emitted from
998 * all buttons (normal, disabled and toggle) even when there is no visible
999 * change in buttons (i.e., buttons do not raise when mouse enters).
1000 * The parameter @p isHighlighted is @p true when mouse enters and @p false when
1001 * mouse exits.
1002 */
1003 void highlighted(int id, bool isHighlighted);
1004
1005 /**
1006 * This signal is emitted when item id gets highlighted/unhighlighted
1007 * (i.e when mouse enters/exits).
1008 *
1009 * Note that this signal is emitted from
1010 * all buttons (normal, disabled and toggle) even when there is no visible
1011 * change in buttons (i.e., buttons do not raise when mouse enters).
1012 */
1013 void highlighted(int id );
1014
1015 /**
1016 * Emitted when toolbar changes position, or when
1017 * an item is removed from toolbar.
1018 *
1019 * If you subclass @ref KMainWindow and reimplement
1020 * @ref KMainWindow::resizeEvent() be sure to connect to
1021 * this signal. Note: You can connect this signal to a slot that
1022 * doesn't take parameter.
1023 */
1024 void moved( BarPosition );
1025
1026 /**
1027 * @internal
1028 * This signal is emitted when toolbar detects changing of
1029 * following parameters:
1030 * highlighting, button-size, button-mode. This signal is
1031 * internal, aimed to buttons.
1032 */
1033 void modechange ();
1034
1035 /**
1036 * This signal is emitted when the toolbar is getting deleted,
1037 * and before ~KToolbar finishes (so it's still time to remove
1038 * widgets from the toolbar).
1039 * Used by KWidgetAction.
1040 * @since 3.2
1041 */
1042 void toolbarDestroyed();
1043
1044public:
1045 /**
1046 * @return global setting for "Highlight buttons under mouse"
1047 */
1048 static bool highlightSetting();
1049
1050 /**
1051 * @return global setting for "Toolbars transparent when moving"
1052 */
1053 static bool transparentSetting();
1054
1055 /**
1056 * @return global setting for "Icon Text"
1057 */
1058 static IconText iconTextSetting();
1059
1060public slots:
1061 virtual void setIconText( const QString &txt )
1062 { QToolBar::setIconText( txt ); }
1063
1064protected:
1065 void mousePressEvent( QMouseEvent * );
1066 void childEvent( QChildEvent *e );
1067 void showEvent( QShowEvent *e );
1068 void resizeEvent( QResizeEvent *e );
1069 bool event( QEvent *e );
1070 void applyAppearanceSettings(KConfig *config, const QString &_configGroup, bool forceGlobal = false);
1071 QString settingsGroup();
1072
1073private slots:
1074 void rebuildLayout();
1075 void slotReadConfig ();
1076 void slotAppearanceChanged();
1077 void slotIconChanged(int);
1078 void slotRepaint();
1079 void toolBarPosChanged( QToolBar *tb );
1080 void slotContextAboutToShow();
1081 void widgetDestroyed();
1082
1083private:
1084 void init( bool readConfig = true, bool honorStyle = false );
1085 void doConnections( KToolBarButton *button );
1086 void insertWidgetInternal( QWidget *w, int &index, int id );
1087 void removeWidgetInternal( QWidget *w );
1088 void getAttributes( QString &position, QString &icontext, int &index );
1089//US KPopupMenu *contextMenu();
1090 QPopupMenu *contextMenu();
1091
1092 QMap<QWidget*, int > widget2id;
1093 typedef QMap<int, QWidget* > Id2WidgetMap;
1094 Id2WidgetMap id2widget;
1095//US KPopupMenu *context;
1096 QPopupMenu *context;
1097 QPtrList<QWidget> widgets;
1098 QTimer *layoutTimer;
1099 QGuardedPtr<QWidget> stretchableWidget, rightAligned;
1100protected:
1101 virtual void virtual_hook( int id, void* data );
1102private:
1103 KToolBarPrivate *d;
1104 bool inshutdownprocess;
1105};
1106
1107#endif
diff --git a/microkde/kdeui/ktoolbarbutton.cpp b/microkde/kdeui/ktoolbarbutton.cpp
new file mode 100644
index 0000000..1d5d0e5
--- a/dev/null
+++ b/microkde/kdeui/ktoolbarbutton.cpp
@@ -0,0 +1,756 @@
1/* This file is part of the KDE libraries
2 Copyright (C) 1997, 1998 Stephan Kulow (coolo@kde.org)
3 (C) 1997, 1998 Mark Donohoe (donohoe@kde.org)
4 (C) 1997, 1998 Sven Radej (radej@kde.org)
5 (C) 1997, 1998 Matthias Ettrich (ettrich@kde.org)
6 (C) 1999 Chris Schlaeger (cs@kde.org)
7 (C) 1999 Kurt Granroth (granroth@kde.org)
8
9 This library is free software; you can redistribute it and/or
10 modify it under the terms of the GNU Library General Public
11 License version 2 as published by the Free Software Foundation.
12
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Library General Public License for more details.
17
18 You should have received a copy of the GNU Library General Public License
19 along with this library; see the file COPYING.LIB. If not, write to
20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA.
22*/
23
24//US #include <config.h>
25#include <string.h>
26
27#include "ktoolbarbutton.h"
28#include "ktoolbar.h"
29
30#include <qstyle.h>
31#include <qimage.h>
32#include <qtimer.h>
33#include <qdrawutil.h>
34#include <qtooltip.h>
35#include <qbitmap.h>
36#include <qpopupmenu.h>
37#include <qcursor.h>
38#include <qpainter.h>
39#include <qlayout.h>
40
41#include <kapplication.h>
42#include <kdebug.h>
43#include <kglobal.h>
44#include <kglobalsettings.h>
45//US #include <kiconeffect.h>
46#include <kiconloader.h>
47
48// needed to get our instance
49#include <kmainwindow.h>
50
51template class QIntDict<KToolBarButton>;
52
53class KToolBarButtonPrivate
54{
55public:
56 KToolBarButtonPrivate()
57 {
58 m_noStyle = false;
59 m_isSeparator = false;
60 m_isRadio = false;
61 m_highlight = false;
62 m_isRaised = false;
63 m_isActive = false;
64
65 m_iconName = QString::null;
66 m_iconText = KToolBar::IconOnly;
67 m_iconSize = 0;
68
69//US m_instance = KGlobal::instance();
70 }
71 ~KToolBarButtonPrivate()
72 {
73 }
74
75 int m_id;
76 bool m_noStyle: 1;
77 bool m_isSeparator: 1;
78 bool m_isRadio: 1;
79 bool m_highlight: 1;
80 bool m_isRaised: 1;
81 bool m_isActive: 1;
82
83 QString m_iconName;
84
85 KToolBar *m_parent;
86 KToolBar::IconText m_iconText;
87 int m_iconSize;
88 QSize size;
89
90 QPoint m_mousePressPos;
91
92//US KInstance *m_instance;
93};
94
95// This will construct a separator
96KToolBarButton::KToolBarButton( QWidget *_parent, const char *_name )
97 : QToolButton( _parent , _name)
98{
99 d = new KToolBarButtonPrivate;
100
101 resize(6,6);
102 hide();
103 d->m_isSeparator = true;
104}
105
106KToolBarButton::KToolBarButton( const QString& _icon, int _id,
107 QWidget *_parent, const char *_name,
108 const QString &_txt/*US, KInstance *_instance*/ )
109 : QToolButton( _parent, _name ), d( 0 )
110{
111 d = new KToolBarButtonPrivate;
112
113 d->m_id = _id;
114 d->m_parent = (KToolBar*)_parent;
115 QToolButton::setTextLabel(_txt);
116//US d->m_instance = _instance;
117
118 setFocusPolicy( NoFocus );
119
120 // connect all of our slots and start trapping events
121 connect(d->m_parent, SIGNAL( modechange() ),
122 this, SLOT( modeChange() ));
123
124 connect(this, SIGNAL( clicked() ),
125 this, SLOT( slotClicked() ) );
126 connect(this, SIGNAL( pressed() ),
127 this, SLOT( slotPressed() ) );
128 connect(this, SIGNAL( released() ),
129 this, SLOT( slotReleased() ) );
130 installEventFilter(this);
131
132 d->m_iconName = _icon;
133
134 // do our initial setup
135 modeChange();
136}
137
138KToolBarButton::KToolBarButton( const QPixmap& pixmap, int _id,
139 QWidget *_parent, const char *name,
140 const QString& txt)
141 : QToolButton( _parent, name ), d( 0 )
142{
143 d = new KToolBarButtonPrivate;
144
145 d->m_id = _id;
146 d->m_parent = (KToolBar *) _parent;
147 QToolButton::setTextLabel(txt);
148
149 setFocusPolicy( NoFocus );
150
151 // connect all of our slots and start trapping events
152 connect(d->m_parent, SIGNAL( modechange()),
153 this, SLOT(modeChange()));
154
155 connect(this, SIGNAL( clicked() ),
156 this, SLOT( slotClicked() ));
157 connect(this, SIGNAL( pressed() ),
158 this, SLOT( slotPressed() ));
159 connect(this, SIGNAL( released() ),
160 this, SLOT( slotReleased() ));
161 installEventFilter(this);
162
163 // set our pixmap and do our initial setup
164 setIconSet( QIconSet( pixmap ));
165 modeChange();
166}
167
168KToolBarButton::~KToolBarButton()
169{
170 delete d; d = 0;
171}
172
173void KToolBarButton::modeChange()
174{
175 QSize mysize;
176
177 // grab a few global variables for use in this function and others
178 d->m_highlight = d->m_parent->highlight();
179 d->m_iconText = d->m_parent->iconText();
180
181 d->m_iconSize = d->m_parent->iconSize();
182 if (!d->m_iconName.isNull())
183 setIcon(d->m_iconName);
184
185 // we'll start with the size of our pixmap
186 int pix_width = d->m_iconSize;
187
188 if ( d->m_iconSize == 0 ) {
189 if (!strcmp(d->m_parent->name(), "mainToolBar"))
190/*US
191 pix_width = IconSize( KIcon::MainToolbar );
192 else
193 pix_width = IconSize( KIcon::Toolbar );
194*/
195//qDebug("KToolBarButton::modeChange make iconsize configurable");
196 pix_width = 16;
197 }
198 int pix_height = pix_width;
199
200 int text_height = 0;
201 int text_width = 0;
202
203 QToolTip::remove(this);
204 if (d->m_iconText != KToolBar::IconOnly)
205 {
206 // okay, we have to deal with fonts. let's get our information now
207/*US
208 QFont tmp_font = KGlobalSettings::toolBarFont();
209
210 // now parse out our font sizes from our chosen font
211 QFontMetrics fm(tmp_font);
212
213 text_height = fm.lineSpacing();
214 text_width = fm.width(textLabel());
215*/
216//qDebug("KToolBarButton::modeChange make textsize configurable");
217
218 // none of the other modes want tooltips
219 }
220 else
221 {
222 QToolTip::add(this, textLabel());
223 }
224
225 switch (d->m_iconText)
226 {
227 case KToolBar::IconOnly:
228 mysize = QSize(pix_width, pix_height);
229 break;
230
231 case KToolBar::IconTextRight:
232 mysize = QSize(pix_width + text_width + 4, pix_height);
233 break;
234
235 case KToolBar::TextOnly:
236 mysize = QSize(text_width + 4, text_height);
237 break;
238
239 case KToolBar::IconTextBottom:
240 mysize = QSize((text_width + 4 > pix_width) ? text_width + 4 : pix_width, pix_height + text_height);
241 break;
242
243 default:
244 break;
245 }
246/*US
247 mysize = style().sizeFromContents(QStyle::CT_ToolButton, this, mysize).
248 expandedTo(QApplication::globalStrut());
249*/
250 // make sure that this isn't taller then it is wide
251 if (mysize.height() > mysize.width())
252 mysize.setWidth(mysize.height());
253
254 d->size = mysize;
255 setFixedSize(mysize);
256 updateGeometry();
257}
258
259void KToolBarButton::setTextLabel( const QString& text, bool tipToo)
260{
261 if (text.isNull())
262 return;
263
264 QString txt(text);
265 if (txt.right(3) == QString::fromLatin1("..."))
266 txt.truncate(txt.length() - 3);
267
268 QToolButton::setTextLabel(txt, tipToo);
269 update();
270}
271
272void KToolBarButton::setText( const QString& text)
273{
274 setTextLabel(text, true);
275 modeChange();
276}
277
278void KToolBarButton::setIcon( const QString &icon )
279{
280 d->m_iconName = icon;
281 d->m_iconSize = d->m_parent->iconSize();
282 // QObject::name() return "const char *" instead of QString.
283 if (!strcmp(d->m_parent->name(), "mainToolBar"))
284/*US QToolButton::setIconSet( d->m_instance->iconLoader()->loadIconSet(
285 d->m_iconName, KIcon::MainToolbar, d->m_iconSize ));
286*/
287 QToolButton::setIconSet( KGlobal::iconLoader()->loadIconSet(d->m_iconName ));
288 else
289/*US QToolButton::setIconSet(d->m_instance->iconLoader()->loadIconSet(
290 d->m_iconName, KIcon::Toolbar, d->m_iconSize ));
291*/
292 QToolButton::setIconSet(KGlobal::iconLoader()->loadIconSet(d->m_iconName));
293}
294
295void KToolBarButton::setIconSet( const QIconSet &iconset )
296{
297 QToolButton::setIconSet( iconset );
298}
299
300// remove?
301void KToolBarButton::setPixmap( const QPixmap &pixmap )
302{
303 if( pixmap.isNull()) // called by QToolButton
304 {
305 QToolButton::setPixmap( pixmap );
306 return;
307 }
308 QIconSet set = iconSet();
309 set.setPixmap( pixmap, QIconSet::Automatic, QIconSet::Active );
310 QToolButton::setIconSet( set );
311}
312
313void KToolBarButton::setDefaultPixmap( const QPixmap &pixmap )
314{
315 QIconSet set = iconSet();
316 set.setPixmap( pixmap, QIconSet::Automatic, QIconSet::Normal );
317 QToolButton::setIconSet( set );
318}
319
320void KToolBarButton::setDisabledPixmap( const QPixmap &pixmap )
321{
322 QIconSet set = iconSet();
323 set.setPixmap( pixmap, QIconSet::Automatic, QIconSet::Disabled );
324 QToolButton::setIconSet( set );
325}
326
327void KToolBarButton::setDefaultIcon( const QString& icon )
328{
329 QIconSet set = iconSet();
330 QPixmap pm;
331 if (!strcmp(d->m_parent->name(), "mainToolBar"))
332 pm = /*US d->m_instance->iconLoader()*/KGlobal::iconLoader()->loadIcon( icon, KIcon::MainToolbar,
333 d->m_iconSize );
334 else
335 pm = /*US d->m_instance->iconLoader()*/KGlobal::iconLoader()->loadIcon( icon, KIcon::Toolbar,
336 d->m_iconSize );
337 set.setPixmap( pm, QIconSet::Automatic, QIconSet::Normal );
338 QToolButton::setIconSet( set );
339}
340
341void KToolBarButton::setDisabledIcon( const QString& icon )
342{
343 QIconSet set = iconSet();
344 QPixmap pm;
345 if (!strcmp(d->m_parent->name(), "mainToolBar"))
346 pm = /*US d->m_instance->iconLoader()*/ KGlobal::iconLoader()->loadIcon( icon, KIcon::MainToolbar,
347 d->m_iconSize );
348 else
349 pm = /*US d->m_instance->iconLoader()*/ KGlobal::iconLoader()->loadIcon( icon, KIcon::Toolbar,
350 d->m_iconSize );
351 set.setPixmap( pm, QIconSet::Automatic, QIconSet::Disabled );
352 QToolButton::setIconSet( set );
353}
354
355QPopupMenu *KToolBarButton::popup()
356{
357 // obsolete
358 // KDE4: remove me
359 return QToolButton::popup();
360}
361
362void KToolBarButton::setPopup(QPopupMenu *p, bool)
363{
364 QToolButton::setPopup(p);
365 QToolButton::setPopupDelay(1);
366}
367
368
369void KToolBarButton::setDelayedPopup (QPopupMenu *p, bool)
370{
371 QToolButton::setPopup(p);
372//US QToolButton::setPopupDelay(QApplication::startDragTime());
373}
374
375void KToolBarButton::leaveEvent(QEvent *)
376{
377 if( d->m_isRaised || d->m_isActive )
378 {
379 d->m_isRaised = false;
380 d->m_isActive = false;
381 repaint(false);
382 }
383
384 emit highlighted(d->m_id, false);
385}
386
387void KToolBarButton::enterEvent(QEvent *)
388{
389 if (d->m_highlight)
390 {
391 if (isEnabled())
392 {
393 d->m_isActive = true;
394 if (!isToggleButton())
395 d->m_isRaised = true;
396 }
397 else
398 {
399 d->m_isRaised = false;
400 d->m_isActive = false;
401 }
402
403 repaint(false);
404 }
405 emit highlighted(d->m_id, true);
406}
407
408bool KToolBarButton::eventFilter(QObject *o, QEvent *ev)
409{
410 if ((KToolBarButton *)o == this)
411 {
412
413 // Popup the menu when the left mousebutton is pressed and the mouse
414 // is moved by a small distance.
415 if (QToolButton::popup())
416 {
417 if (ev->type() == QEvent::MouseButtonPress)
418 {
419 QMouseEvent* mev = static_cast<QMouseEvent*>(ev);
420 d->m_mousePressPos = mev->pos();
421 }
422 else if (ev->type() == QEvent::MouseMove)
423 {
424 QMouseEvent* mev = static_cast<QMouseEvent*>(ev);
425 if ((mev->pos() - d->m_mousePressPos).manhattanLength()
426//US > KGlobalSettings::dndEventDelay())
427 > 5 )
428 {
429//US openPopup();
430 return true;
431 }
432 }
433 }
434
435 if ((ev->type() == QEvent::MouseButtonPress ||
436 ev->type() == QEvent::MouseButtonRelease ||
437 ev->type() == QEvent::MouseButtonDblClick) && d->m_isRadio && isOn())
438 return true;
439
440 // From Kai-Uwe Sattler <kus@iti.CS.Uni-Magdeburg.De>
441 if (ev->type() == QEvent::MouseButtonDblClick)
442 {
443 emit doubleClicked(d->m_id);
444 return true;
445 }
446 }
447
448 return QToolButton::eventFilter(o, ev);
449}
450
451void KToolBarButton::drawButton( QPainter *_painter )
452{
453#ifdef DESKTOP_VERSION
454 QStyle::SFlags flags = QStyle::Style_Default;
455 QStyle::SCFlags active = QStyle::SC_None;
456
457 if (isDown()) {
458 flags |= QStyle::Style_Down;
459 active |= QStyle::SC_ToolButton;
460 }
461 if (isEnabled()) flags |= QStyle::Style_Enabled;
462 if (isOn()) flags |= QStyle::Style_On;
463 if (isEnabled() && d->m_isRaised)flags |= QStyle::Style_Raised;
464 if (hasFocus())flags |= QStyle::Style_HasFocus;
465
466 // Draw a styled toolbutton
467 style().drawComplexControl(QStyle::CC_ToolButton, _painter, this, rect(),
468 colorGroup(), flags, QStyle::SC_ToolButton, active, QStyleOption());
469
470#else
471 style().drawToolButton(_painter, rect().x(), rect().y(), rect().width(), rect().height(), colorGroup());
472#endif
473 int dx, dy;
474 QFont tmp_font(KGlobalSettings::toolBarFont());
475 QFontMetrics fm(tmp_font);
476 QRect textRect;
477 int textFlags = 0;
478
479 if (d->m_iconText == KToolBar::IconOnly) // icon only
480 {
481/*US
482 QPixmap pixmap = iconSet().pixmap( QIconSet::Automatic,
483 isEnabled() ? (d->m_isActive ? QIconSet::Active : QIconSet::Normal) :
484 QIconSet::Disabled,
485 isOn() ? QIconSet::On : QIconSet::Off );
486*/
487 QPixmap pixmap = iconSet().pixmap( QIconSet::Automatic,
488 isEnabled() ? (d->m_isActive ? QIconSet::Active : QIconSet::Normal) :
489 QIconSet::Disabled);
490
491 if( !pixmap.isNull())
492 {
493 dx = ( width() - pixmap.width() ) / 2;
494 dy = ( height() - pixmap.height() ) / 2;
495 if ( isDown() /*US && style().styleHint(QStyle::SH_GUIStyle) == WindowsStyle*/ )
496 {
497 ++dx;
498 ++dy;
499 }
500 _painter->drawPixmap( dx, dy, pixmap );
501 }
502 }
503 else if (d->m_iconText == KToolBar::IconTextRight) // icon and text (if any)
504 {
505/*US
506 QPixmap pixmap = iconSet().pixmap( QIconSet::Automatic,
507 isEnabled() ? (d->m_isActive ? QIconSet::Active : QIconSet::Normal) :
508 QIconSet::Disabled,
509 isOn() ? QIconSet::On : QIconSet::Off );
510*/
511 QPixmap pixmap = iconSet().pixmap( QIconSet::Automatic,
512 isEnabled() ? (d->m_isActive ? QIconSet::Active : QIconSet::Normal) :
513 QIconSet::Disabled);
514
515 if( !pixmap.isNull())
516 {
517 dx = 4;
518 dy = ( height() - pixmap.height() ) / 2;
519 if ( isDown() /*US && style().styleHint(QStyle::SH_GUIStyle) == WindowsStyle*/ )
520 {
521 ++dx;
522 ++dy;
523 }
524 _painter->drawPixmap( dx, dy, pixmap );
525 }
526
527 if (!textLabel().isNull())
528 {
529 textFlags = AlignVCenter|AlignLeft;
530 if (!pixmap.isNull())
531 dx = 4 + pixmap.width() + 2;
532 else
533 dx = 4;
534 dy = 0;
535 if ( isDown() /*US && style().styleHint(QStyle::SH_GUIStyle) == WindowsStyle*/ )
536 {
537 ++dx;
538 ++dy;
539 }
540 textRect = QRect(dx, dy, width()-dx, height());
541 }
542 }
543 else if (d->m_iconText == KToolBar::TextOnly)
544 {
545 if (!textLabel().isNull())
546 {
547 textFlags = AlignVCenter|AlignLeft;
548 dx = (width() - fm.width(textLabel())) / 2;
549 dy = (height() - fm.lineSpacing()) / 2;
550 if ( isDown() /*US && style().styleHint(QStyle::SH_GUIStyle) == WindowsStyle*/ )
551 {
552 ++dx;
553 ++dy;
554 }
555 textRect = QRect( dx, dy, fm.width(textLabel()), fm.lineSpacing() );
556 }
557 }
558 else if (d->m_iconText == KToolBar::IconTextBottom)
559 {
560/*US
561 QPixmap pixmap = iconSet().pixmap( QIconSet::Automatic,
562 isEnabled() ? (d->m_isActive ? QIconSet::Active : QIconSet::Normal) :
563 QIconSet::Disabled,
564 isOn() ? QIconSet::On : QIconSet::Off );
565*/
566 QPixmap pixmap = iconSet().pixmap( QIconSet::Automatic,
567 isEnabled() ? (d->m_isActive ? QIconSet::Active : QIconSet::Normal) :
568 QIconSet::Disabled);
569
570 if( !pixmap.isNull())
571 {
572 dx = (width() - pixmap.width()) / 2;
573 dy = (height() - fm.lineSpacing() - pixmap.height()) / 2;
574 if ( isDown() /*US && style().styleHint(QStyle::SH_GUIStyle) == WindowsStyle*/ )
575 {
576 ++dx;
577 ++dy;
578 }
579 _painter->drawPixmap( dx, dy, pixmap );
580 }
581
582 if (!textLabel().isNull())
583 {
584 textFlags = AlignBottom|AlignHCenter;
585 dx = (width() - fm.width(textLabel())) / 2;
586 dy = height() - fm.lineSpacing() - 4;
587
588 if ( isDown() /*US && style().styleHint(QStyle::SH_GUIStyle) == WindowsStyle*/ )
589 {
590 ++dx;
591 ++dy;
592 }
593 textRect = QRect( dx, dy, fm.width(textLabel()), fm.lineSpacing() );
594 }
595 }
596
597 // Draw the text at the position given by textRect, and using textFlags
598 if (!textLabel().isNull() && !textRect.isNull())
599 {
600 _painter->setFont(KGlobalSettings::toolBarFont());
601 if (!isEnabled())
602 _painter->setPen(palette().disabled().dark());
603 else if(d->m_isRaised)
604 _painter->setPen(KGlobalSettings::toolBarHighlightColor());
605 else
606 _painter->setPen( colorGroup().buttonText() );
607 _painter->drawText(textRect, textFlags, textLabel());
608 }
609
610 if (QToolButton::popup())
611 {
612#ifdef DESKTOP_VERSION
613 QStyle::SFlags arrowFlags = QStyle::Style_Default;
614
615 if (isDown())arrowFlags |= QStyle::Style_Down;
616 if (isEnabled()) arrowFlags |= QStyle::Style_Enabled;
617
618 style().drawPrimitive(QStyle::PE_ArrowDown, _painter,
619 QRect(width()-7, height()-7, 7, 7), colorGroup(),
620 arrowFlags, QStyleOption() );
621#else
622 style().drawArrow(_painter, Qt::DownArrow, isDown(),
623 width()-7, height()-7, 7, 7, colorGroup(), isEnabled() );
624#endif
625
626 }
627}
628
629void KToolBarButton::paletteChange(const QPalette &)
630{
631 if(!d->m_isSeparator)
632 {
633 modeChange();
634 repaint(false); // no need to delete it first therefore only false
635 }
636}
637
638void KToolBarButton::showMenu()
639{
640 // obsolete
641 // KDE4: remove me
642}
643
644void KToolBarButton::slotDelayTimeout()
645{
646 // obsolete
647 // KDE4: remove me
648}
649
650void KToolBarButton::slotClicked()
651{
652 emit clicked( d->m_id );
653}
654
655void KToolBarButton::slotPressed()
656{
657 emit pressed( d->m_id );
658}
659
660void KToolBarButton::slotReleased()
661{
662 emit released( d->m_id );
663}
664
665void KToolBarButton::slotToggled()
666{
667 emit toggled( d->m_id );
668}
669
670void KToolBarButton::setNoStyle(bool no_style)
671{
672 d->m_noStyle = no_style;
673
674 modeChange();
675 d->m_iconText = KToolBar::IconTextRight;
676 repaint(false);
677}
678
679void KToolBarButton::setRadio (bool f)
680{
681 if ( d )
682 d->m_isRadio = f;
683}
684
685void KToolBarButton::on(bool flag)
686{
687 if(isToggleButton() == true)
688 setOn(flag);
689 else
690 {
691 setDown(flag);
692 leaveEvent((QEvent *) 0);
693 }
694 repaint();
695}
696
697void KToolBarButton::toggle()
698{
699 setOn(!isOn());
700 repaint();
701}
702
703void KToolBarButton::setToggle(bool flag)
704{
705 setToggleButton(flag);
706 if (flag == true)
707 connect(this, SIGNAL(toggled(bool)), this, SLOT(slotToggled()));
708 else
709 disconnect(this, SIGNAL(toggled(bool)), this, SLOT(slotToggled()));
710}
711
712QSize KToolBarButton::sizeHint() const
713{
714 return d->size;
715}
716
717QSize KToolBarButton::minimumSizeHint() const
718{
719 return d->size;
720}
721
722QSize KToolBarButton::minimumSize() const
723{
724 return d->size;
725}
726
727bool KToolBarButton::isRaised() const
728{
729 return d->m_isRaised;
730}
731
732bool KToolBarButton::isActive() const
733{
734 return d->m_isActive;
735}
736
737int KToolBarButton::iconTextMode() const
738{
739 return static_cast<int>( d->m_iconText );
740}
741
742int KToolBarButton::id() const
743{
744 return d->m_id;
745}
746
747// KToolBarButtonList
748KToolBarButtonList::KToolBarButtonList()
749{
750 setAutoDelete(false);
751}
752
753void KToolBarButton::virtual_hook( int, void* )
754{ /*BASE::virtual_hook( id, data );*/ }
755
756//US #include "ktoolbarbutton.moc"
diff --git a/microkde/kdeui/ktoolbarbutton.h b/microkde/kdeui/ktoolbarbutton.h
new file mode 100644
index 0000000..9aaa13c
--- a/dev/null
+++ b/microkde/kdeui/ktoolbarbutton.h
@@ -0,0 +1,313 @@
1/* This file is part of the KDE libraries
2 Copyright (C) 1997, 1998 Stephan Kulow (coolo@kde.org)
3 (C) 1997, 1998 Sven Radej (radej@kde.org)
4 (C) 1997, 1998 Mark Donohoe (donohoe@kde.org)
5 (C) 1997, 1998 Matthias Ettrich (ettrich@kde.org)
6 (C) 2000 Kurt Granroth (granroth@kde.org)
7
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Library General Public
10 License version 2 as published by the Free Software Foundation.
11
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Library General Public License for more details.
16
17 You should have received a copy of the GNU Library General Public License
18 along with this library; see the file COPYING.LIB. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.
21*/
22
23// $Id$
24#ifndef _KTOOLBARBUTTON_H
25#define _KTOOLBARBUTTON_H
26
27#include <qpixmap.h>
28#include <qtoolbutton.h>
29#include <qintdict.h>
30#include <qstring.h>
31#include <kglobal.h>
32
33class KToolBar;
34class KToolBarButtonPrivate;
35//USclass KInstance;
36class QEvent;
37class QPopupMenu;
38class QPainter;
39
40/**
41 * A toolbar button. This is used internally by @ref KToolBar, use the
42 * KToolBar methods instead.
43 * @internal
44 */
45class KToolBarButton : public QToolButton
46{
47 Q_OBJECT
48
49public:
50 /**
51 * Construct a button with an icon loaded by the button itself.
52 * This will trust the button to load the correct icon with the
53 * correct size.
54 *
55 * @param icon Name of icon to load (may be absolute or relative)
56 * @param id Id of this button
57 * @param parent This button's parent
58 * @param name This button's internal name
59 * @param txt This button's text (in a tooltip or otherwise)
60 */
61 KToolBarButton(const QString& icon, int id, QWidget *parent,
62 const char *name=0L, const QString &txt=QString::null/*US,
63 KInstance *_instance = KGlobal::instance()*/);
64
65 /**
66 * Construct a button with an existing pixmap. It is not
67 * recommended that you use this as the internal icon loading code
68 * will almost always get it "right".
69 *
70 * @param icon Name of icon to load (may be absolute or relative)
71 * @param id Id of this button
72 * @param parent This button's parent
73 * @param name This button's internal name
74 * @param txt This button's text (in a tooltip or otherwise)
75 */
76 KToolBarButton(const QPixmap& pixmap, int id, QWidget *parent,
77 const char *name=0L, const QString &txt=QString::null);
78
79 /**
80 * Construct a separator button
81 *
82 * @param parent This button's parent
83 * @param name This button's internal name
84 */
85 KToolBarButton(QWidget *parent=0L, const char *name=0L);
86
87 /**
88 * Standard destructor
89 */
90 ~KToolBarButton();
91 QSize sizeHint() const;
92 QSize minimumSizeHint() const;
93 QSize minimumSize() const;
94
95#ifndef KDE_NO_COMPAT
96 /**
97 * @deprecated
98 * Set the pixmap directly for this button. This pixmap should be
99 * the active one... the dimmed and disabled pixmaps are constructed
100 * based on this one. However, don't use this function unless you
101 * are positive that you don't want to use @ref setIcon.
102 *
103 * @param pixmap The active pixmap
104 */
105 // this one is from QButton, so #ifdef-ing it out doesn't break BC
106 virtual void setPixmap(const QPixmap &pixmap);
107
108 /**
109 * @deprecated
110 * Force the button to use this pixmap as the default one rather
111 * then generating it using effects.
112 *
113 * @param pixmap The pixmap to use as the default (normal) one
114 */
115 void setDefaultPixmap(const QPixmap& pixmap);
116
117 /**
118 * @deprecated
119 * Force the button to use this pixmap when disabled one rather then
120 * generating it using effects.
121 *
122 * @param pixmap The pixmap to use when disabled
123 */
124 void setDisabledPixmap(const QPixmap& pixmap);
125#endif
126
127 /**
128 * Set the text for this button. The text will be either used as a
129 * tooltip (IconOnly) or will be along side the icon
130 *
131 * @param text The button (or tooltip) text
132 */
133 virtual void setText(const QString &text);
134
135 /**
136 * Set the icon for this button. The icon will be loaded internally
137 * with the correct size. This function is preferred over @ref setIconSet
138 *
139 * @param icon The name of the icon
140 */
141 virtual void setIcon(const QString &icon);
142
143 /// @since 3.1
144 virtual void setIcon( const QPixmap &pixmap )
145 { QToolButton::setIcon( pixmap ); }
146
147 /**
148 * Set the pixmaps for this toolbar button from a QIconSet.
149 * If you call this you don't need to call any of the other methods
150 * that set icons or pixmaps.
151 * @param iconset The iconset to use
152 */
153 virtual void setIconSet( const QIconSet &iconset );
154
155#ifndef KDE_NO_COMPAT
156 /**
157 * @deprecated
158 * Set the active icon for this button. The pixmap itself is loaded
159 * internally based on the icon size... .. the disabled and default
160 * pixmaps, however will only be constructed if @ref #generate is
161 * true. This function is preferred over @ref setPixmap
162 *
163 * @param icon The name of the active icon
164 * @param generate If true, then the other icons are automagically
165 * generated from this one
166 */
167 void setIcon(const QString &icon, bool /*generate*/ ) { setIcon( icon ); }
168
169 /**
170 * @deprecated
171 * Force the button to use this icon as the default one rather
172 * then generating it using effects.
173 *
174 * @param icon The icon to use as the default (normal) one
175 */
176 void setDefaultIcon(const QString& icon);
177
178 /**
179 * @deprecated
180 * Force the button to use this icon when disabled one rather then
181 * generating it using effects.
182 *
183 * @param icon The icon to use when disabled
184 */
185 void setDisabledIcon(const QString& icon);
186#endif
187
188 /**
189 * Turn this button on or off
190 *
191 * @param flag true or false
192 */
193 void on(bool flag = true);
194
195 /**
196 * Toggle this button
197 */
198 void toggle();
199
200 /**
201 * Turn this button into a toggle button or disable the toggle
202 * aspects of it. This does not toggle the button itself.
203 * Use @ref toggle() for that.
204 *
205 * @param toggle true or false
206 */
207 void setToggle(bool toggle = true);
208
209 /**
210 * Return a pointer to this button's popup menu (if it exists)
211 */
212 QPopupMenu *popup();
213
214 /**
215 * Returns the button's id.
216 * @since 3.2
217 */
218 int id() const;
219
220 /**
221 * Give this button a popup menu. There will not be a delay when
222 * you press the button. Use @ref setDelayedPopup if you want that
223 * behavior.
224 *
225 * @param p The new popup menu
226 */
227 void setPopup (QPopupMenu *p, bool unused = false);
228
229 /**
230 * Gives this button a delayed popup menu.
231 *
232 * This function allows you to add a delayed popup menu to the button.
233 * The popup menu is then only displayed when the button is pressed and
234 * held down for about half a second.
235 *
236 * @param p the new popup menu
237 */
238 void setDelayedPopup(QPopupMenu *p, bool unused = false);
239
240 /**
241 * Turn this button into a radio button
242 *
243 * @param f true or false
244 */
245 void setRadio(bool f = true);
246
247 /**
248 * Toolbar buttons naturally will assume the global styles
249 * concerning icons, icons sizes, etc. You can use this function to
250 * explicitely turn this off, if you like.
251 *
252 * @param no_style Will disable styles if true
253 */
254 void setNoStyle(bool no_style = true);
255
256signals:
257 void clicked(int);
258 void doubleClicked(int);
259 void pressed(int);
260 void released(int);
261 void toggled(int);
262 void highlighted(int, bool);
263
264public slots:
265 /**
266 * This slot should be called whenever the toolbar mode has
267 * potentially changed. This includes such events as text changing,
268 * orientation changing, etc.
269 */
270 void modeChange();
271 virtual void setTextLabel(const QString&, bool tipToo);
272
273protected:
274 void paletteChange(const QPalette &);
275 void leaveEvent(QEvent *e);
276 void enterEvent(QEvent *e);
277 void drawButton(QPainter *p);
278 bool eventFilter (QObject *o, QEvent *e);
279 void showMenu();
280
281 /// @since 3.1
282 bool isRaised() const;
283 /// @since 3.1
284 bool isActive() const;
285 /// @since 3.1
286 int iconTextMode() const;
287
288protected slots:
289 void slotClicked();
290 void slotPressed();
291 void slotReleased();
292 void slotToggled();
293 void slotDelayTimeout();
294
295protected:
296 virtual void virtual_hook( int id, void* data );
297private:
298 KToolBarButtonPrivate *d;
299};
300
301/**
302* List of @ref KToolBarButton objects.
303* @internal
304* @version $Id$
305*/
306class KToolBarButtonList : public QIntDict<KToolBarButton>
307{
308public:
309 KToolBarButtonList();
310 ~KToolBarButtonList() {}
311};
312
313#endif
diff --git a/microkde/kdeui/ktoolbarhandler.cpp b/microkde/kdeui/ktoolbarhandler.cpp
new file mode 100644
index 0000000..7b97233
--- a/dev/null
+++ b/microkde/kdeui/ktoolbarhandler.cpp
@@ -0,0 +1,253 @@
1/* This file is part of the KDE libraries
2 Copyright (C) 2002 Simon Hausmann <hausmann@kde.org>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License version 2 as published by the Free Software Foundation.
7
8 This library is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 Library General Public License for more details.
12
13 You should have received a copy of the GNU Library General Public License
14 along with this library; see the file COPYING.LIB. If not, write to
15 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16 Boston, MA 02111-1307, USA.
17*/
18
19#include "ktoolbarhandler.h"
20
21#include <qpopupmenu.h>
22#include <kapplication.h>
23#include <ktoolbar.h>
24#include <kmainwindow.h>
25#include <klocale.h>
26#include <kaction.h>
27#include <assert.h>
28
29namespace
30{
31 const char *actionListName = "show_menu_and_toolbar_actionlist";
32
33 const char *guiDescription = ""
34 "<!DOCTYPE kpartgui><kpartgui name=\"StandardToolBarMenuHandler\">"
35 "<MenuBar>"
36 " <Menu name=\"settings\">"
37 " <ActionList name=\"%1\" />"
38 " </Menu>"
39 "</MenuBar>"
40 "</kpartgui>";
41
42 const char *resourceFileName = "barhandler.rc";
43
44 class BarActionBuilder
45 {
46 public:
47 BarActionBuilder( KActionCollection *actionCollection, KMainWindow *mainWindow, QPtrList<KToolBar> &oldToolBarList )
48 : m_actionCollection( actionCollection ), m_mainWindow( mainWindow ), m_needsRebuild( false )
49 {
50/*US
51 QPtrList<QDockWindow> dockWindows = m_mainWindow->dockWindows();
52 QPtrListIterator<QDockWindow> dockWindowIt( dockWindows );
53 for ( ; dockWindowIt.current(); ++dockWindowIt ) {
54
55//US KToolBar *toolBar = dynamic_cast<KToolBar *>( dockWindowIt.current() );
56 KToolBar *toolBar = (KToolBar *)( dockWindowIt.current() );
57 if ( !toolBar )
58 continue;
59
60 if ( oldToolBarList.findRef( toolBar ) == -1 )
61 m_needsRebuild = true;
62
63 m_toolBars.append( toolBar );
64 }
65*/
66 if ( !m_needsRebuild )
67 m_needsRebuild = ( oldToolBarList.count() != m_toolBars.count() );
68
69 }
70
71 bool needsRebuild() const { return m_needsRebuild; }
72
73 QPtrList<KAction> create()
74 {
75 if ( !m_needsRebuild )
76 return QPtrList<KAction>();
77
78 QPtrListIterator<KToolBar> toolBarIt( m_toolBars );
79 for ( ; toolBarIt.current(); ++toolBarIt )
80 handleToolBar( toolBarIt.current() );
81
82 QPtrList<KAction> actions;
83
84 if ( m_toolBarActions.count() == 0 )
85 return actions;
86
87 if ( m_toolBarActions.count() == 1 ) {
88 m_toolBarActions.getFirst()->setText( i18n( "Show Toolbar" ) );
89 return m_toolBarActions;
90 }
91
92 KActionMenu *menuAction = new KActionMenu( i18n( "Toolbars" ), m_actionCollection, "toolbars_submenu_action" );
93
94 QPtrListIterator<KAction> actionIt( m_toolBarActions );
95 for ( ; actionIt.current(); ++actionIt )
96 menuAction->insert( actionIt.current() );
97
98 actions.append( menuAction );
99 return actions;
100 }
101
102 const QPtrList<KToolBar> &toolBars() const { return m_toolBars; }
103
104 private:
105 void handleToolBar( KToolBar *toolBar )
106 {
107 KAction *action = new KToggleToolBarAction( toolBar,
108 i18n( "Show %1" ).arg( toolBar->label() ),
109 m_actionCollection,
110 toolBar->name() );
111
112 m_toolBarActions.append( action );
113 }
114
115 KActionCollection *m_actionCollection;
116 KMainWindow *m_mainWindow;
117
118 QPtrList<KToolBar> m_toolBars;
119 QPtrList<KAction> m_toolBarActions;
120
121 bool m_needsRebuild : 1;
122 };
123}
124
125using namespace KDEPrivate;
126
127ToolBarHandler::ToolBarHandler( KMainWindow *mainWindow, const char *name )
128 : QObject( mainWindow, name ), KXMLGUIClient( mainWindow )
129{
130 init( mainWindow );
131}
132
133ToolBarHandler::ToolBarHandler( KMainWindow *mainWindow, QObject *parent, const char *name )
134 : QObject( parent, name ), KXMLGUIClient( mainWindow )
135{
136 init( mainWindow );
137}
138
139ToolBarHandler::~ToolBarHandler()
140{
141 m_actions.setAutoDelete( true );
142 m_actions.clear();
143}
144
145KAction *ToolBarHandler::toolBarMenuAction()
146{
147 assert( m_actions.count() == 1 );
148 return m_actions.getFirst();
149}
150
151void ToolBarHandler::setupActions()
152{
153//US if ( !factory() || !m_mainWindow )
154 if ( !m_mainWindow )
155 return;
156
157 BarActionBuilder builder( actionCollection(), m_mainWindow, m_toolBars );
158
159 if ( !builder.needsRebuild() )
160 return;
161
162 unplugActionList( actionListName );
163
164 m_actions.setAutoDelete( true );
165
166 m_actions.clear();
167 m_actions.setAutoDelete( false );
168
169 m_actions = builder.create();
170
171 /*
172 for ( QPtrListIterator<KToolBar> toolBarIt( m_toolBars );
173 toolBarIt.current(); ++toolBarIt )
174 toolBarIt.current()->disconnect( this );
175 */
176
177 m_toolBars = builder.toolBars();
178
179 /*
180 for ( QPtrListIterator<KToolBar> toolBarIt( m_toolBars );
181 toolBarIt.current(); ++toolBarIt )
182 connect( toolBarIt.current(), SIGNAL( destroyed() ),
183 this, SLOT( setupActions() ) );
184 */
185
186//US if (kapp && kapp->authorizeKAction("options_show_toolbar"))
187 plugActionList( actionListName, m_actions );
188
189 connectToActionContainers();
190}
191
192/*US
193void ToolBarHandler::clientAdded( KXMLGUIClient *client )
194{
195 if ( client == this )
196 setupActions();
197}
198*/
199
200void ToolBarHandler::init( KMainWindow *mainWindow )
201{
202 d = 0;
203 m_mainWindow = mainWindow;
204
205/*US
206 connect( m_mainWindow->guiFactory(), SIGNAL( clientAdded( KXMLGUIClient * ) ),
207 this, SLOT( clientAdded( KXMLGUIClient * ) ) );
208*/
209 /* re-use an existing resource file if it exists. can happen if the user launches the
210 * toolbar editor */
211 /*
212 setXMLFile( resourceFileName );
213 */
214/*US
215 if ( domDocument().documentElement().isNull() ) {
216
217 QString completeDescription = QString::fromLatin1( guiDescription )
218 .arg( actionListName );
219
220 setXML( completeDescription, false*/ /*merge*/ /*);
221 }
222*/
223}
224
225void ToolBarHandler::connectToActionContainers()
226{
227 QPtrListIterator<KAction> actionIt( m_actions );
228 for ( ; actionIt.current(); ++actionIt )
229 connectToActionContainer( actionIt.current() );
230}
231
232void ToolBarHandler::connectToActionContainer( KAction *action )
233{
234 uint containerCount = action->containerCount();
235 for ( uint i = 0; i < containerCount; ++i )
236 connectToActionContainer( action->container( i ) );
237}
238
239void ToolBarHandler::connectToActionContainer( QWidget *container )
240{
241//US QPopupMenu *popupMenu = dynamic_cast<QPopupMenu *>( container );
242 QPopupMenu *popupMenu = (QPopupMenu *)( container );
243 if ( !popupMenu )
244 return;
245
246 connect( popupMenu, SIGNAL( aboutToShow() ),
247 this, SLOT( setupActions() ) );
248}
249
250//US #include "ktoolbarhandler.moc"
251
252/* vim: et sw=4 ts=4
253 */
diff --git a/microkde/kdeui/ktoolbarhandler.h b/microkde/kdeui/ktoolbarhandler.h
new file mode 100644
index 0000000..a1340ae
--- a/dev/null
+++ b/microkde/kdeui/ktoolbarhandler.h
@@ -0,0 +1,70 @@
1/* This file is part of the KDE libraries
2 Copyright (C) 2002 Simon Hausmann <hausmann@kde.org>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License version 2 as published by the Free Software Foundation.
7
8 This library is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 Library General Public License for more details.
12
13 You should have received a copy of the GNU Library General Public License
14 along with this library; see the file COPYING.LIB. If not, write to
15 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16 Boston, MA 02111-1307, USA.
17*/
18
19#ifndef KBARHANDLER_H
20#define KBARHANDLER_H
21
22#include <qobject.h>
23#include <qguardedptr.h>
24#include <qptrlist.h>
25#include <kxmlguiclient.h>
26#include <kaction.h>
27
28class KMainWindow;
29class KToolBar;
30
31namespace KDEPrivate
32{
33
34/// @since 3.1
35class ToolBarHandler : public QObject, public KXMLGUIClient
36{
37 Q_OBJECT
38public:
39 ToolBarHandler( KMainWindow *mainWindow, const char *name = 0 );
40 ToolBarHandler( KMainWindow *mainWindow, QObject *parent, const char *name = 0 );
41 virtual ~ToolBarHandler();
42
43 KAction *toolBarMenuAction();
44
45public slots:
46 void setupActions();
47
48private slots:
49//US void clientAdded( KXMLGUIClient *client );
50
51private:
52 void init( KMainWindow *mainWindow );
53 void connectToActionContainers();
54 void connectToActionContainer( KAction *action );
55 void connectToActionContainer( QWidget *container );
56
57 struct Data;
58 Data *d;
59
60 QGuardedPtr<KMainWindow> m_mainWindow;
61 QPtrList<KAction> m_actions;
62 QPtrList<KToolBar> m_toolBars;
63};
64
65} // namespace KDEPrivate
66
67#endif // KBARHANDLER_H
68
69/* vim: et sw=4 ts=4
70 */
diff --git a/microkde/kdeui/kxmlguiclient.cpp b/microkde/kdeui/kxmlguiclient.cpp
new file mode 100644
index 0000000..073e30b
--- a/dev/null
+++ b/microkde/kdeui/kxmlguiclient.cpp
@@ -0,0 +1,958 @@
1/* This file is part of the KDE libraries
2 Copyright (C) 2000 Simon Hausmann <hausmann@kde.org>
3 Copyright (C) 2000 Kurt Granroth <granroth@kde.org>
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License version 2 as published by the Free Software Foundation.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA.
18*/
19
20#include "kxmlguiclient.h"
21
22/*US
23#include "kxmlguifactory.h"
24#include "kxmlguibuilder.h"
25*/
26
27/*US
28#include <qdir.h>
29#include <qfile.h>
30#include <qdom.h>
31#include <qtextstream.h>
32#include <qregexp.h>
33*/
34
35//US #include <kinstance.h>
36#include <kstandarddirs.h>
37#include <kdebug.h>
38#include <kaction.h>
39#include <kapplication.h>
40
41#include <assert.h>
42
43class KXMLGUIClientPrivate
44{
45public:
46 KXMLGUIClientPrivate()
47 {
48//US m_instance = KGlobal::instance();
49//US m_factory = 0L;
50 m_parent = 0L;
51//US m_builder = 0L;
52 m_actionCollection = 0;
53 }
54 ~KXMLGUIClientPrivate()
55 {
56 }
57
58//US KInstance *m_instance;
59
60//US QDomDocument m_doc;
61 KActionCollection *m_actionCollection;
62//US QDomDocument m_buildDocument;
63//US KXMLGUIFactory *m_factory;
64 KXMLGUIClient *m_parent;
65 //QPtrList<KXMLGUIClient> m_supers;
66 QPtrList<KXMLGUIClient> m_children;
67//US KXMLGUIBuilder *m_builder;
68//US QString m_xmlFile;
69//US QString m_localXMLFile;
70};
71
72KXMLGUIClient::KXMLGUIClient()
73{
74 d = new KXMLGUIClientPrivate;
75}
76
77KXMLGUIClient::KXMLGUIClient( KXMLGUIClient *parent )
78{
79 d = new KXMLGUIClientPrivate;
80 parent->insertChildClient( this );
81}
82
83KXMLGUIClient::~KXMLGUIClient()
84{
85 if ( d->m_parent )
86 d->m_parent->removeChildClient( this );
87
88 QPtrListIterator<KXMLGUIClient> it( d->m_children );
89 for ( ; it.current(); ++it ) {
90 assert( it.current()->d->m_parent == this );
91 it.current()->d->m_parent = 0;
92 }
93
94 delete d->m_actionCollection;
95 delete d;
96}
97
98KAction *KXMLGUIClient::action( const char *name ) const
99{
100 KAction* act = actionCollection()->action( name );
101 if ( !act ) {
102 QPtrListIterator<KXMLGUIClient> childIt( d->m_children );
103 for (; childIt.current(); ++childIt ) {
104 act = childIt.current()->actionCollection()->action( name );
105 if ( act )
106 break;
107 }
108 }
109 return act;
110}
111
112KActionCollection *KXMLGUIClient::actionCollection() const
113{
114 if ( !d->m_actionCollection )
115 d->m_actionCollection = new KActionCollection( 0, 0,
116 "KXMLGUILClient-KActionCollection" );
117 return d->m_actionCollection;
118}
119
120/*US
121KAction *KXMLGUIClient::action( const QDomElement &element ) const
122{
123 static const QString &attrName = KGlobal::staticQString( "name" );
124 return actionCollection()->action( element.attribute( attrName ).latin1() );
125}
126
127KInstance *KXMLGUIClient::instance() const
128{
129 return d->m_instance;
130}
131
132QDomDocument KXMLGUIClient::domDocument() const
133{
134 return d->m_doc;
135}
136
137QString KXMLGUIClient::xmlFile() const
138{
139 return d->m_xmlFile;
140}
141
142QString KXMLGUIClient::localXMLFile() const
143{
144 if ( !d->m_localXMLFile.isEmpty() )
145 return d->m_localXMLFile;
146
147 if ( d->m_xmlFile[0] == '/' )
148 return QString::null; // can't save anything here
149
150 return locateLocal( "data", QString::fromLatin1( instance()->instanceName() + '/' ) + d->m_xmlFile );
151}
152
153
154void KXMLGUIClient::reloadXML()
155{
156 QString file( xmlFile() );
157 if ( !file.isEmpty() )
158 setXMLFile( file );
159}
160
161void KXMLGUIClient::setInstance( KInstance *instance )
162{
163 d->m_instance = instance;
164 actionCollection()->setInstance( instance );
165 if ( d->m_builder )
166 d->m_builder->setBuilderClient( this );
167}
168
169void KXMLGUIClient::setXMLFile( const QString& _file, bool merge, bool setXMLDoc )
170{
171 // store our xml file name
172 if ( !_file.isNull() ) {
173 d->m_xmlFile = _file;
174 actionCollection()->setXMLFile( _file );
175 }
176
177 if ( !setXMLDoc )
178 return;
179
180 QString file = _file;
181 if ( file[0] != '/' )
182 {
183 QString doc;
184
185 QString filter = QString::fromLatin1( instance()->instanceName() + '/' ) + _file;
186
187 QStringList allFiles = instance()->dirs()->findAllResources( "data", filter ) + instance()->dirs()->findAllResources( "data", _file );
188
189 file = findMostRecentXMLFile( allFiles, doc );
190
191 if ( file.isEmpty() )
192 {
193 // this might or might not be an error. for the time being,
194 // let's treat this as if it isn't a problem and the user just
195 // wants the global standards file
196 setXML( QString::null, true );
197 return;
198 }
199 else if ( !doc.isEmpty() )
200 {
201 setXML( doc, merge );
202 return;
203 }
204 }
205
206 QString xml = KXMLGUIFactory::readConfigFile( file );
207 setXML( xml, merge );
208}
209
210void KXMLGUIClient::setLocalXMLFile( const QString &file )
211{
212 d->m_localXMLFile = file;
213}
214
215void KXMLGUIClient::setXML( const QString &document, bool merge )
216{
217 QDomDocument doc;
218 doc.setContent( document );
219 setDOMDocument( doc, merge );
220}
221
222void KXMLGUIClient::setDOMDocument( const QDomDocument &document, bool merge )
223{
224 if ( merge )
225 {
226 QDomElement base = d->m_doc.documentElement();
227
228 QDomElement e = document.documentElement();
229 KXMLGUIFactory::removeDOMComments( e );
230
231 // merge our original (global) xml with our new one
232 mergeXML(base, e, actionCollection());
233
234 // reassign our pointer as mergeXML might have done something
235 // strange to it
236 base = d->m_doc.documentElement();
237
238 // we want some sort of failsafe.. just in case
239 if ( base.isNull() )
240 d->m_doc = document;
241 }
242 else
243 {
244 d->m_doc = document;
245 KXMLGUIFactory::removeDOMComments( d->m_doc );
246 }
247
248 setXMLGUIBuildDocument( QDomDocument() );
249}
250*/
251
252/*US
253bool KXMLGUIClient::mergeXML( QDomElement &base, const QDomElement &additive, KActionCollection *actionCollection )
254{
255 static const QString &tagAction = KGlobal::staticQString( "Action" );
256 static const QString &tagMerge = KGlobal::staticQString( "Merge" );
257 static const QString &tagSeparator = KGlobal::staticQString( "Separator" );
258 static const QString &attrName = KGlobal::staticQString( "name" );
259 static const QString &attrAppend = KGlobal::staticQString( "append" );
260 static const QString &attrWeakSeparator = KGlobal::staticQString( "weakSeparator" );
261 static const QString &tagMergeLocal = KGlobal::staticQString( "MergeLocal" );
262 static const QString &tagText = KGlobal::staticQString( "text" );
263 static const QString &attrAlreadyVisited = KGlobal::staticQString( "alreadyVisited" );
264 static const QString &attrNoMerge = KGlobal::staticQString( "noMerge" );
265 static const QString &attrOne = KGlobal::staticQString( "1" );
266
267 // there is a possibility that we don't want to merge in the
268 // additive.. rather, we might want to *replace* the base with the
269 // additive. this can be for any container.. either at a file wide
270 // level or a simple container level. we look for the 'noMerge'
271 // tag, in any event and just replace the old with the new
272 if ( additive.attribute(attrNoMerge) == attrOne ) // ### use toInt() instead? (Simon)
273 {
274 base.parentNode().replaceChild(additive, base);
275 return true;
276 }
277
278 QString tag;
279
280 QDomElement e = base.firstChild().toElement();
281 // iterate over all elements in the container (of the global DOM tree)
282 while ( !e.isNull() )
283 {
284 tag = e.tagName();
285
286 // if there's an action tag in the global tree and the action is
287 // not implemented, then we remove the element
288 if ( tag == tagAction )
289 {
290 QCString name = e.attribute( attrName ).utf8(); // WABA
291 if ( !actionCollection->action( name ) ||
292 (kapp && !kapp->authorizeKAction(name)))
293 {
294 // remove this child as we aren't using it
295 QDomElement oldChild = e;
296 e = e.nextSibling().toElement();
297 base.removeChild( oldChild );
298 continue;
299 }
300 }
301
302 // if there's a separator defined in the global tree, then add an
303 // attribute, specifying that this is a "weak" separator
304 else if ( tag == tagSeparator )
305 {
306 e.setAttribute( attrWeakSeparator, (uint)1 );
307
308 // okay, hack time. if the last item was a weak separator OR
309 // this is the first item in a container, then we nuke the
310 // current one
311 QDomElement prev = e.previousSibling().toElement();
312 if ( prev.isNull() ||
313 ( prev.tagName() == tagSeparator && !prev.attribute( attrWeakSeparator ).isNull() ) ||
314 ( prev.tagName() == tagText ) )
315 {
316 // the previous element was a weak separator or didn't exist
317 QDomElement oldChild = e;
318 e = e.nextSibling().toElement();
319 base.removeChild( oldChild );
320 continue;
321 }
322 }
323
324 // the MergeLocal tag lets us specify where non-standard elements
325 // of the local tree shall be merged in. After inserting the
326 // elements we delete this element
327 else if ( tag == tagMergeLocal )
328 {
329 QDomElement currElement = e;
330
331 // switch our iterator "e" to the next sibling, so that we don't
332 // process the local tree's inserted items!
333 e = e.nextSibling().toElement();
334
335 QDomElement it = additive.firstChild().toElement();
336 while ( !it.isNull() )
337 {
338 QDomElement newChild = it;
339
340 it = it.nextSibling().toElement();
341
342 if ( newChild.tagName() == tagText )
343 continue;
344
345 if ( newChild.attribute( attrAlreadyVisited ) == attrOne )
346 continue;
347
348 QString itAppend( newChild.attribute( attrAppend ) );
349 QString elemName( currElement.attribute( attrName ) );
350
351 if ( ( itAppend.isNull() && elemName.isEmpty() ) ||
352 ( itAppend == elemName ) )
353 {
354 // first, see if this new element matches a standard one in
355 // the global file. if it does, then we skip it as it will
356 // be merged in, later
357 QDomElement matchingElement = findMatchingElement( newChild, base );
358 if ( matchingElement.isNull() || newChild.tagName() == tagSeparator )
359 base.insertBefore( newChild, currElement );
360 }
361 }
362
363 base.removeChild( currElement );
364 continue;
365 }
366
367 // in this last case we check for a separator tag and, if not, we
368 // can be sure that its a container --> proceed with child nodes
369 // recursively and delete the just proceeded container item in
370 // case its empty (if the recursive call returns true)
371 else if ( tag != tagMerge )
372 {
373 // handle the text tag
374 if ( tag == tagText )
375 {
376 e = e.nextSibling().toElement();
377 continue;
378 }
379
380 QDomElement matchingElement = findMatchingElement( e, additive );
381
382 QDomElement currElement = e;
383 e = e.nextSibling().toElement();
384
385 if ( !matchingElement.isNull() )
386 {
387 matchingElement.setAttribute( attrAlreadyVisited, (uint)1 );
388
389 if ( mergeXML( currElement, matchingElement, actionCollection ) )
390 {
391 base.removeChild( currElement );
392 continue;
393 }
394
395 // Merge attributes
396 QDomNamedNodeMap attribs = matchingElement.attributes();
397 for(uint i = 0; i < attribs.count(); i++)
398 {
399 QDomNode node = attribs.item(i);
400 currElement.setAttribute(node.nodeName(), node.nodeValue());
401 }
402
403 continue;
404 }
405 else
406 {
407 // this is an important case here! We reach this point if the
408 // "local" tree does not contain a container definition for
409 // this container. However we have to call mergeXML recursively
410 // and make it check if there are actions implemented for this
411 // container. *If* none, then we can remove this container now
412 if ( mergeXML( currElement, QDomElement(), actionCollection ) )
413 base.removeChild( currElement );
414 continue;
415 }
416 }
417
418 //I think this can be removed ;-)
419 e = e.nextSibling().toElement();
420 }
421
422 //here we append all child elements which were not inserted
423 //previously via the LocalMerge tag
424 e = additive.firstChild().toElement();
425 while ( !e.isNull() )
426 {
427 QDomElement matchingElement = findMatchingElement( e, base );
428
429 if ( matchingElement.isNull() )
430 {
431 QDomElement newChild = e;
432 e = e.nextSibling().toElement();
433 base.appendChild( newChild );
434 }
435 else
436 e = e.nextSibling().toElement();
437 }
438
439 // do one quick check to make sure that the last element was not
440 // a weak separator
441 QDomElement last = base.lastChild().toElement();
442 if ( (last.tagName() == tagSeparator) && (!last.attribute( attrWeakSeparator ).isNull()) )
443 {
444 base.removeChild( base.lastChild() );
445 }
446
447 // now we check if we are empty (in which case we return "true", to
448 // indicate the caller that it can delete "us" (the base element
449 // argument of "this" call)
450 bool deleteMe = true;
451 e = base.firstChild().toElement();
452 for ( ; !e.isNull(); e = e.nextSibling().toElement() )
453 {
454 tag = e.tagName();
455
456 if ( tag == tagAction )
457 {
458 // if base contains an implemented action, then we must not get
459 // deleted (note that the actionCollection contains both,
460 // "global" and "local" actions
461 if ( actionCollection->action( e.attribute( attrName ).utf8() ) )
462 {
463 deleteMe = false;
464 break;
465 }
466 }
467 else if ( tag == tagSeparator )
468 {
469 // if we have a separator which has *not* the weak attribute
470 // set, then it must be owned by the "local" tree in which case
471 // we must not get deleted either
472 QString weakAttr = e.attribute( attrWeakSeparator );
473 if ( weakAttr.isEmpty() || weakAttr.toInt() != 1 )
474 {
475 deleteMe = false;
476 break;
477 }
478 }
479
480 // in case of a merge tag we have unlimited lives, too ;-)
481 else if ( tag == tagMerge )
482 {
483// deleteMe = false;
484// break;
485 continue;
486 }
487
488 // a text tag is NOT enough to spare this container
489 else if ( tag == tagText )
490 {
491 continue;
492 }
493
494 // what's left are non-empty containers! *don't* delete us in this
495 // case (at this position we can be *sure* that the container is
496 // *not* empty, as the recursive call for it was in the first loop
497 // which deleted the element in case the call returned "true"
498 else
499 {
500 deleteMe = false;
501 break;
502 }
503 }
504
505 return deleteMe;
506}
507
508QDomElement KXMLGUIClient::findMatchingElement( const QDomElement &base, const QDomElement &additive )
509{
510 static const QString &tagAction = KGlobal::staticQString( "Action" );
511 static const QString &tagMergeLocal = KGlobal::staticQString( "MergeLocal" );
512 static const QString &attrName = KGlobal::staticQString( "name" );
513
514 QDomElement e = additive.firstChild().toElement();
515 for ( ; !e.isNull(); e = e.nextSibling().toElement() )
516 {
517 // skip all action and merge tags as we will never use them
518 if ( ( e.tagName() == tagAction ) || ( e.tagName() == tagMergeLocal ) )
519 {
520 continue;
521 }
522
523 // now see if our tags are equivalent
524 if ( ( e.tagName() == base.tagName() ) &&
525 ( e.attribute( attrName ) == base.attribute( attrName ) ) )
526 {
527 return e;
528 }
529 }
530
531 // nope, return a (now) null element
532 return e;
533}
534
535void KXMLGUIClient::conserveMemory()
536{
537 d->m_doc = QDomDocument();
538 d->m_buildDocument = QDomDocument();
539}
540
541void KXMLGUIClient::setXMLGUIBuildDocument( const QDomDocument &doc )
542{
543 d->m_buildDocument = doc;
544}
545
546QDomDocument KXMLGUIClient::xmlguiBuildDocument() const
547{
548 return d->m_buildDocument;
549}
550*/
551
552/*US
553void KXMLGUIClient::setFactory( KXMLGUIFactory *factory )
554{
555 d->m_factory = factory;
556}
557
558KXMLGUIFactory *KXMLGUIClient::factory() const
559{
560 return d->m_factory;
561}
562*/
563KXMLGUIClient *KXMLGUIClient::parentClient() const
564{
565 return d->m_parent;
566}
567
568void KXMLGUIClient::insertChildClient( KXMLGUIClient *child )
569{
570 if ( child->d->m_parent )
571 child->d->m_parent->removeChildClient( child );
572 d->m_children.append( child );
573 child->d->m_parent = this;
574}
575
576void KXMLGUIClient::removeChildClient( KXMLGUIClient *child )
577{
578 assert( d->m_children.containsRef( child ) );
579 d->m_children.removeRef( child );
580 child->d->m_parent = 0;
581}
582
583/*bool KXMLGUIClient::addSuperClient( KXMLGUIClient *super )
584{
585 if ( d->m_supers.contains( super ) )
586 return false;
587 d->m_supers.append( super );
588 return true;
589}*/
590
591const QPtrList<KXMLGUIClient> *KXMLGUIClient::childClients()
592{
593 return &d->m_children;
594}
595/*US
596void KXMLGUIClient::setClientBuilder( KXMLGUIBuilder *builder )
597{
598 d->m_builder = builder;
599 if ( builder )
600 builder->setBuilderInstance( instance() );
601}
602
603KXMLGUIBuilder *KXMLGUIClient::clientBuilder() const
604{
605 return d->m_builder;
606}
607*/
608
609void KXMLGUIClient::plugActionList( const QString &name, const QPtrList<KAction> &actionList )
610{
611/*US
612 if ( !d->m_factory )
613 return;
614
615 d->m_factory->plugActionList( this, name, actionList );
616*/
617}
618
619void KXMLGUIClient::unplugActionList( const QString &name )
620{
621/*US
622 if ( !d->m_factory )
623 return;
624
625 d->m_factory->unplugActionList( this, name );
626*/
627}
628
629/*US
630QString KXMLGUIClient::findMostRecentXMLFile( const QStringList &files, QString &doc )
631{
632
633 QValueList<DocStruct> allDocuments;
634
635 QStringList::ConstIterator it = files.begin();
636 QStringList::ConstIterator end = files.end();
637 for (; it != end; ++it )
638 {
639 //kdDebug() << "KXMLGUIClient::findMostRecentXMLFile " << *it << endl;
640 QString data = KXMLGUIFactory::readConfigFile( *it );
641 DocStruct d;
642 d.file = *it;
643 d.data = data;
644 allDocuments.append( d );
645 }
646
647 QValueList<DocStruct>::Iterator best = allDocuments.end();
648 uint bestVersion = 0;
649
650 QValueList<DocStruct>::Iterator docIt = allDocuments.begin();
651 QValueList<DocStruct>::Iterator docEnd = allDocuments.end();
652 for (; docIt != docEnd; ++docIt )
653 {
654 QString versionStr = findVersionNumber( (*docIt).data );
655 if ( versionStr.isEmpty() )
656 continue;
657
658 bool ok = false;
659 uint version = versionStr.toUInt( &ok );
660 if ( !ok )
661 continue;
662 //kdDebug() << "FOUND VERSION " << version << endl;
663
664 if ( version > bestVersion )
665 {
666 best = docIt;
667 //kdDebug() << "best version is now " << version << endl;
668 bestVersion = version;
669 }
670 }
671
672 if ( best != docEnd )
673 {
674 if ( best != allDocuments.begin() )
675 {
676 QValueList<DocStruct>::Iterator local = allDocuments.begin();
677
678 // load the local document and extract the action properties
679 QDomDocument document;
680 document.setContent( (*local).data );
681
682 ActionPropertiesMap properties = extractActionProperties( document );
683
684 // in case the document has a ActionProperties section
685 // we must not delete it but copy over the global doc
686 // to the local and insert the ActionProperties section
687 if ( !properties.isEmpty() )
688 {
689 // now load the global one with the higher version number
690 // into memory
691 document.setContent( (*best).data );
692 // and store the properties in there
693 storeActionProperties( document, properties );
694
695 (*local).data = document.toString();
696 // make sure we pick up the new local doc, when we return later
697 best = local;
698
699 // write out the new version of the local document
700 QFile f( (*local).file );
701 if ( f.open( IO_WriteOnly ) )
702 {
703 QCString utf8data = (*local).data.utf8();
704 f.writeBlock( utf8data.data(), utf8data.length() );
705 f.close();
706 }
707 }
708 else
709 {
710 QString f = (*local).file;
711 QString backup = f + QString::fromLatin1( ".backup" );
712 QDir dir;
713 dir.rename( f, backup );
714 }
715 }
716 doc = (*best).data;
717 return (*best).file;
718 }
719 else if ( files.count() > 0 )
720 {
721 //kdDebug() << "returning first one..." << endl;
722 doc = (*allDocuments.begin()).data;
723 return (*allDocuments.begin()).file;
724 }
725
726 return QString::null;
727}
728
729
730
731QString KXMLGUIClient::findVersionNumber( const QString &xml )
732{
733 enum { ST_START, ST_AFTER_OPEN, ST_AFTER_GUI,
734 ST_EXPECT_VERSION, ST_VERSION_NUM} state = ST_START;
735 for (unsigned int pos = 0; pos < xml.length(); pos++)
736 {
737 switch (state)
738 {
739 case ST_START:
740 if (xml[pos] == '<')
741 state = ST_AFTER_OPEN;
742 break;
743 case ST_AFTER_OPEN:
744 {
745 //Jump to gui..
746 int guipos = xml.find("gui", pos, false);
747 if (guipos == -1)
748 return QString::null; //Reject
749
750 pos = guipos + 2; //Position at i, so we're moved ahead to the next character by the ++;
751 state = ST_AFTER_GUI;
752 break;
753 }
754 case ST_AFTER_GUI:
755 state = ST_EXPECT_VERSION;
756 break;
757 case ST_EXPECT_VERSION:
758 {
759 int verpos = xml.find("version=\"", pos, false );
760 if (verpos == -1)
761 return QString::null; //Reject
762
763 pos = verpos + 8; //v = 0, e = +1, r = +2, s = +3 , i = +4, o = +5, n = +6, = = +7, " = + 8
764 state = ST_VERSION_NUM;
765 break;
766 }
767 case ST_VERSION_NUM:
768 {
769 unsigned int endpos;
770 for (endpos = pos; endpos < xml.length(); endpos++)
771 {
772 if (xml[endpos].unicode() >= '0' && xml[endpos].unicode() <= '9')
773 continue; //Number..
774 if (xml[endpos].unicode() == '"') //End of parameter
775 break;
776 else //This shouldn't be here..
777 {
778 endpos = xml.length();
779 }
780 }
781
782 if (endpos != pos && endpos < xml.length() )
783 {
784 QString matchCandidate = xml.mid(pos, endpos - pos); //Don't include " ".
785 return matchCandidate;
786 }
787
788 state = ST_EXPECT_VERSION; //Try to match a well-formed version..
789 break;
790 } //case..
791 } //switch
792 } //for
793
794 return QString::null;
795}
796
797KXMLGUIClient::ActionPropertiesMap KXMLGUIClient::extractActionProperties( const QDomDocument &doc )
798{
799 ActionPropertiesMap properties;
800
801 QDomElement actionPropElement = doc.documentElement().namedItem( "ActionProperties" ).toElement();
802
803 if ( actionPropElement.isNull() )
804 return properties;
805
806 QDomNode n = actionPropElement.firstChild();
807 for (; !n.isNull(); n = n.nextSibling() )
808 {
809 QDomElement e = n.toElement();
810 if ( e.isNull() )
811 continue;
812
813 if ( e.tagName().lower() != "action" )
814 continue;
815
816 QString actionName = e.attribute( "name" );
817
818 if ( actionName.isEmpty() )
819 continue;
820
821 QMap<QString, QMap<QString, QString> >::Iterator propIt = properties.find( actionName );
822 if ( propIt == properties.end() )
823 propIt = properties.insert( actionName, QMap<QString, QString>() );
824
825 QDomNamedNodeMap attributes = e.attributes();
826 for ( uint i = 0; i < attributes.length(); ++i )
827 {
828 QDomAttr attr = attributes.item( i ).toAttr();
829
830 if ( attr.isNull() )
831 continue;
832
833 QString name = attr.name();
834
835 if ( name == "name" || name.isEmpty() )
836 continue;
837
838 (*propIt)[ name ] = attr.value();
839 }
840
841 }
842
843 return properties;
844}
845
846void KXMLGUIClient::storeActionProperties( QDomDocument &doc, const ActionPropertiesMap &properties )
847{
848 QDomElement actionPropElement = doc.documentElement().namedItem( "ActionProperties" ).toElement();
849
850 if ( actionPropElement.isNull() )
851 {
852 actionPropElement = doc.createElement( "ActionProperties" );
853 doc.documentElement().appendChild( actionPropElement );
854 }
855
856 while ( !actionPropElement.firstChild().isNull() )
857 actionPropElement.removeChild( actionPropElement.firstChild() );
858
859 ActionPropertiesMap::ConstIterator it = properties.begin();
860 ActionPropertiesMap::ConstIterator end = properties.end();
861 for (; it != end; ++it )
862 {
863 QDomElement action = doc.createElement( "Action" );
864 action.setAttribute( "name", it.key() );
865 actionPropElement.appendChild( action );
866
867 QMap<QString, QString> attributes = (*it);
868 QMap<QString, QString>::ConstIterator attrIt = attributes.begin();
869 QMap<QString, QString>::ConstIterator attrEnd = attributes.end();
870 for (; attrIt != attrEnd; ++attrIt )
871 action.setAttribute( attrIt.key(), attrIt.data() );
872 }
873}
874*/
875
876void KXMLGUIClient::addStateActionEnabled(const QString& state,
877 const QString& action)
878{
879 StateChange stateChange = getActionsToChangeForState(state);
880
881 stateChange.actionsToEnable.append( action );
882 //kdDebug() << "KXMLGUIClient::addStateActionEnabled( " << state << ", " << action << ")" << endl;
883
884 m_actionsStateMap.replace( state, stateChange );
885}
886
887
888void KXMLGUIClient::addStateActionDisabled(const QString& state,
889 const QString& action)
890{
891 StateChange stateChange = getActionsToChangeForState(state);
892
893 stateChange.actionsToDisable.append( action );
894 //kdDebug() << "KXMLGUIClient::addStateActionDisabled( " << state << ", " << action << ")" << endl;
895
896 m_actionsStateMap.replace( state, stateChange );
897}
898
899
900KXMLGUIClient::StateChange KXMLGUIClient::getActionsToChangeForState(const QString& state)
901{
902 return m_actionsStateMap[state];
903}
904
905
906void KXMLGUIClient::stateChanged(const QString &newstate, KXMLGUIClient::ReverseStateChange reverse)
907{
908 StateChange stateChange = getActionsToChangeForState(newstate);
909
910 bool setTrue = (reverse == StateNoReverse);
911 bool setFalse = !setTrue;
912
913 // Enable actions which need to be enabled...
914 //
915 for ( QStringList::Iterator it = stateChange.actionsToEnable.begin();
916 it != stateChange.actionsToEnable.end(); ++it ) {
917
918 KAction *action = actionCollection()->action((*it).latin1());
919 if (action) action->setEnabled(setTrue);
920 }
921
922 // and disable actions which need to be disabled...
923 //
924 for ( QStringList::Iterator it = stateChange.actionsToDisable.begin();
925 it != stateChange.actionsToDisable.end(); ++it ) {
926
927 KAction *action = actionCollection()->action((*it).latin1());
928 if (action) action->setEnabled(setFalse);
929 }
930
931}
932/*US
933void KXMLGUIClient::beginXMLPlug( QWidget *w )
934{
935 actionCollection()->beginXMLPlug( w );
936 QPtrListIterator<KXMLGUIClient> childIt( d->m_children );
937 for (; childIt.current(); ++childIt )
938 childIt.current()->actionCollection()->beginXMLPlug( w );
939}
940
941void KXMLGUIClient::endXMLPlug()
942{
943 actionCollection()->endXMLPlug();
944 QPtrListIterator<KXMLGUIClient> childIt( d->m_children );
945 for (; childIt.current(); ++childIt )
946 childIt.current()->actionCollection()->endXMLPlug();
947}
948
949void KXMLGUIClient::prepareXMLUnplug( QWidget * )
950{
951 actionCollection()->prepareXMLUnplug();
952 QPtrListIterator<KXMLGUIClient> childIt( d->m_children );
953 for (; childIt.current(); ++childIt )
954 childIt.current()->actionCollection()->prepareXMLUnplug();
955}
956*/
957void KXMLGUIClient::virtual_hook( int, void* )
958{ /*BASE::virtual_hook( id, data );*/ }
diff --git a/microkde/kdeui/kxmlguiclient.h b/microkde/kdeui/kxmlguiclient.h
new file mode 100644
index 0000000..cd74c8e
--- a/dev/null
+++ b/microkde/kdeui/kxmlguiclient.h
@@ -0,0 +1,361 @@
1/* This file is part of the KDE libraries
2 Copyright (C) 2000 Simon Hausmann <hausmann@kde.org>
3 Copyright (C) 2000 Kurt Granroth <granroth@kde.org>
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License version 2 as published by the Free Software Foundation.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA.
18*/
19#ifndef _KXMLGUICLIENT_H
20#define _KXMLGUICLIENT_H
21
22
23//US #include <qdom.h>
24#include <qptrlist.h>
25#include <qmap.h>
26#include <qstringlist.h>
27
28class QWidget;
29class KAction;
30class KActionCollection;
31class KInstance;
32
33class KXMLGUIClientPrivate;
34class KXMLGUIFactory;
35class KXMLGUIBuilder;
36
37/**
38 *
39 * A KXMLGUIClient can be used with @ref KXMLGUIFactory to create a
40 * GUI from actions and an XML document, and can be dynamically merged
41 * with other KXMLGUIClients.
42 */
43class KXMLGUIClient
44{
45 friend class KEditToolbarWidget; // for setXMLFile(3 args)
46public:
47 /**
48 * Constructs a KXMLGUIClient which can be used with a
49 * @ref KXMLGUIFactory to create a GUI from actions and an XML document, and
50 * which can be dynamically merged with other KXMLGUIClients.
51 */
52 KXMLGUIClient();
53
54 /**
55 * Constructs a KXMLGUIClient which can be used with a @ref KXMLGUIFactory
56 * to create a GUI from actions and an XML document,
57 * and which can be dynamically merged with other KXMLGUIClients.
58 *
59 * This constructor takes an additional @p parent argument, which makes
60 * the client a child client of the parent.
61 *
62 * Child clients are automatically added to the GUI if the parent is added.
63 *
64 */
65 KXMLGUIClient( KXMLGUIClient *parent );
66
67 /**
68 * Destructs the KXMLGUIClient.
69 */
70 virtual ~KXMLGUIClient();
71
72 /**
73 * Retrieves an action of the client by name. If not found, it looks in its child clients.
74 * This method is provided for convenience, as it uses @ref #actionCollection()
75 * to get the action object.
76 */
77 KAction* action( const char* name ) const;
78
79 /**
80 * Retrieves an action for a given @ref QDomElement. The default
81 * implementation uses the "name" attribute to query the action
82 * object via the other action() method.
83 */
84//US virtual KAction *action( const QDomElement &element ) const;
85
86 /**
87 * Retrieves the entire action collection for the GUI client
88 */
89 virtual KActionCollection* actionCollection() const;
90
91 /**
92 * @return The instance (@ref KInstance) for this part.
93 */
94//US virtual KInstance *instance() const;
95
96 /**
97 * @return The parsed XML in a @ref QDomDocument, set by @ref
98 * setXMLFile() or @ref setXML().
99 * This document describes the layout of the GUI.
100 */
101//US virtual QDomDocument domDocument() const;
102
103 /**
104 * This will return the name of the XML file as set by @ref #setXMLFile().
105 * If @ref #setXML() is used directly, then this will return NULL.
106 *
107 * The filename that this returns is obvious for components as each
108 * component has exactly one XML file. In non-components, however,
109 * there are usually two: the global file and the local file. This
110 * function doesn't really care about that, though. It will always
111 * return the last XML file set. This, in almost all cases, will
112 * be the local XML file.
113 *
114 * @return The name of the XML file or QString::null
115 */
116//US virtual QString xmlFile() const;
117
118//US virtual QString localXMLFile() const;
119
120 /**
121 * @internal
122 */
123//US void setXMLGUIBuildDocument( const QDomDocument &doc );
124 /**
125 * @internal
126 */
127//US QDomDocument xmlguiBuildDocument() const;
128
129 /**
130 * This method is called by the @ref KXMLGUIFactory as soon as the client
131 * is added to the KXMLGUIFactory's GUI.
132 */
133//US void setFactory( KXMLGUIFactory *factory );
134 /**
135 * Retrieves a pointer to the @ref KXMLGUIFactory this client is
136 * associated with (will return 0L if the client's GUI has not been built
137 * by a KXMLGUIFactory.
138 */
139//US KXMLGUIFactory *factory() const;
140
141 /**
142 * KXMLGUIClients can form a simple child/parent object tree. This
143 * method returns a pointer to the parent client or 0L if it has no
144 * parent client assigned.
145 */
146 KXMLGUIClient *parentClient() const;
147
148 /**
149 * Use this method to make a client a child client of another client.
150 * Usually you don't need to call this method, as it is called
151 * automatically when using the second constructor, which takes a
152 * arent argument.
153 */
154 void insertChildClient( KXMLGUIClient *child );
155
156 /**
157 * Removes the given @p child from the client's children list.
158 */
159 void removeChildClient( KXMLGUIClient *child );
160
161 /**
162 * Retrieves a list of all child clients.
163 */
164 const QPtrList<KXMLGUIClient> *childClients();
165
166 /**
167 * A client can have an own @ref KXMLGUIBuilder.
168 * Use this method to assign your builder instance to the client (so that the
169 * @ref KXMLGUIFactory can use it when building the client's GUI)
170 *
171 * Client specific guibuilders are useful if you want to create
172 * custom container widgets for your GUI.
173 */
174//US void setClientBuilder( KXMLGUIBuilder *builder );
175
176 /**
177 * Retrieves the client's GUI builder or 0L if no client specific
178 * builder has been assigned via @ref #setClientBuilder()
179 */
180//US KXMLGUIBuilder *clientBuilder() const;
181
182 /**
183 * Forces this client to re-read its XML resource file. This is
184 * intended to be used when you know that the resource file has
185 * changed and you will soon be rebuilding the GUI. It has no
186 * useful effect with non-KParts GUIs, so don't bother using it
187 * unless your app is component based.
188 */
189//US void reloadXML();
190
191 /**
192 * ActionLists are a way for XMLGUI to support dynamic lists of
193 * actions. E.g. if you are writing a file manager, and there is a
194 * menu file whose contents depend on the mimetype of the file that
195 * is selected, then you can achieve this using ActionLists. It
196 * works as follows:
197 * In your xxxui.rc file ( the one that you set in @ref setXMLFile()
198 * ), you put an <ActionList name="xxx"> tag. E.g.
199 * \verbatim
200 * <kpartgui name="xxx_part" version="1">
201 * <MenuBar>
202 * <Menu name="file">
203 * ... <!-- some useful actions-->
204 * <ActionList name="xxx_file_actionlist" />
205 * ... <!-- even more useful actions-->
206 * </Menu>
207 * ...
208 * </MenuBar>
209 * </kpartgui>
210 * \endverbatim
211 *
212 * This tag will get expanded to a list of actions. In the example
213 * above ( a file manager with a dynamic file menu ), you would call
214 * \code
215 * QPtrList<KAction> file_actions;
216 * for( ... )
217 * if( ... )
218 * file_actions.append( cool_action );
219 * unplugActionList( "xxx_file_actionlist" );
220 * plugActionList( "xxx_file_actionlist", file_actions );
221 * \endcode
222 * every time a file is selected, unselected or ...
223 *
224 * \note You should not call createGUI() after calling this
225 * function. In fact, that would remove the newly added
226 * actionlists again...
227 * \note Forgetting to call unplugActionList() before
228 * plugActionList() would leave the previous actions in the
229 * menu too..
230 */
231 void plugActionList( const QString &name, const QPtrList<KAction> &actionList );
232
233 /**
234 * The complement of \ref plugActionList() ...
235 */
236 void unplugActionList( const QString &name );
237
238//US static QString findMostRecentXMLFile( const QStringList &files, QString &doc );
239
240 void addStateActionEnabled(const QString& state, const QString& action);
241
242 void addStateActionDisabled(const QString& state, const QString& action);
243
244 enum ReverseStateChange { StateNoReverse, StateReverse };
245 struct StateChange
246 {
247 QStringList actionsToEnable;
248 QStringList actionsToDisable;
249 };
250
251 StateChange getActionsToChangeForState(const QString& state);
252
253 /// @since 3.1
254//US void beginXMLPlug( QWidget * );
255 /// @since 3.1
256//US void endXMLPlug();
257 /// @since 3.1
258//US void prepareXMLUnplug( QWidget * );
259
260protected:
261 /**
262 * Returns true if client was added to super client list.
263 * Returns false if client was already in list.
264 */
265 //bool addSuperClient( KXMLGUIClient * );
266
267 /**
268 * Sets the instance (@ref KInstance) for this part.
269 *
270 * Call this first in the inherited class constructor.
271 * (At least before @ref setXMLFile().)
272 */
273//US virtual void setInstance( KInstance *instance );
274
275 /**
276 * Sets the name of the rc file containing the XML for the part.
277 *
278 * Call this in the Part-inherited class constructor.
279 *
280 * @param file Either an absolute path for the file, or simply the
281 * filename, which will then be assumed to be installed
282 * in the "data" resource, under a directory named like
283 * the instance.
284 * @param setXML Specify whether to call setXML. Default is true.
285 * and the DOM document at once.
286 **/
287//US virtual void setXMLFile( const QString& file, bool merge = false, bool setXMLDoc = true );
288
289//US virtual void setLocalXMLFile( const QString &file );
290
291 /**
292 * Sets the XML for the part.
293 *
294 * Call this in the Part-inherited class constructor if you
295 * don't call @ref setXMLFile().
296 **/
297//US virtual void setXML( const QString &document, bool merge = false );
298
299 /**
300 * Sets the Document for the part, describing the layout of the GUI.
301 *
302 * Call this in the Part-inherited class constructor if you don't call
303 * @ref setXMLFile or @ref setXML .
304 */
305//US virtual void setDOMDocument( const QDomDocument &document, bool merge = false );
306
307 /**
308 * This function will attempt to give up some memory after the GUI
309 * is built. It should never be used in apps where the GUI may be
310 * rebuilt at some later time (components, for instance).
311 */
312//US virtual void conserveMemory();
313
314 /**
315 * Actions can collectively be assigned a "State". To accomplish this
316 * the respective actions are tagged as <enable> or <disable> in
317 * a <State> </State> group of the XMLfile. During program execution the
318 * programmer can call stateChanged() to set actions to a defined state.
319 *
320 * @param newstate Name of a State in the XMLfile.
321 * @param reverse If the flag reverse is set to StateReverse, the State is reversed.
322 * (actions to be enabled will be disabled and action to be disabled will be enabled)
323 * Default is reverse=false.
324 */
325 virtual void stateChanged(const QString &newstate, ReverseStateChange reverse = StateNoReverse);
326
327 // Use this one for KDE 4.0
328 //virtual void stateChanged(const QString &newstate, bool reverse = false);
329
330private:
331/*US
332 struct DocStruct
333 {
334 QString file;
335 QString data;
336 };
337
338 bool mergeXML( QDomElement &base, const QDomElement &additive,
339 KActionCollection *actionCollection );
340
341 QDomElement findMatchingElement( const QDomElement &base,
342 const QDomElement &additive );
343*/
344 typedef QMap<QString, QMap<QString, QString> > ActionPropertiesMap;
345
346//US static ActionPropertiesMap extractActionProperties( const QDomDocument &doc );
347
348//US static void storeActionProperties( QDomDocument &doc, const ActionPropertiesMap &properties );
349
350//US static QString findVersionNumber( const QString &_xml );
351
352 // Actions to enable/disable on a state change
353 QMap<QString,StateChange> m_actionsStateMap;
354
355protected:
356 virtual void virtual_hook( int id, void* data );
357private:
358 KXMLGUIClientPrivate *d;
359};
360
361#endif
diff --git a/microkde/kdialog.cpp b/microkde/kdialog.cpp
new file mode 100644
index 0000000..3d62cdd
--- a/dev/null
+++ b/microkde/kdialog.cpp
@@ -0,0 +1,17 @@
1
2#include <kdialog.h>
3#include <qapp.h>
4
5
6KDialog::KDialog( QWidget *parent, const char *name, bool modal ) :
7 QDialog( parent, name, modal )
8{
9 ;
10
11}
12
13int KDialog::spacingHint() { return 3; }
14int KDialog::marginHint() { return 3; }
15
16int KDialog::spacingHintSmall() { if (QApplication::desktop()->width() < 700 ) return 1;else return 3; }
17int KDialog::marginHintSmall() { if (QApplication::desktop()->width() < 700 ) return 1;else return 3; }
diff --git a/microkde/kdialog.h b/microkde/kdialog.h
new file mode 100644
index 0000000..703d268
--- a/dev/null
+++ b/microkde/kdialog.h
@@ -0,0 +1,18 @@
1#ifndef MINIKDE_KDIALOG_H
2#define MINIKDE_KDIALOG_H
3
4#include <qdialog.h>
5
6class KDialog : public QDialog
7{
8 Q_OBJECT
9 public:
10 KDialog( QWidget *parent=0, const char *name=0, bool modal=true );
11
12 static int spacingHint();
13 static int marginHint();
14 static int spacingHintSmall();
15 static int marginHintSmall();
16};
17
18#endif
diff --git a/microkde/kdialogbase.cpp b/microkde/kdialogbase.cpp
new file mode 100644
index 0000000..2ea2053
--- a/dev/null
+++ b/microkde/kdialogbase.cpp
@@ -0,0 +1,278 @@
1#include <qtabwidget.h>
2#include <qpushbutton.h>
3#include <qlayout.h>
4#include <qframe.h>
5
6
7#include "klocale.h"
8#include "kdebug.h"
9
10#include "kdialogbase.h"
11
12KDialogBase::KDialogBase()
13{
14}
15
16KDialogBase::KDialogBase( QWidget *parent, const char *name, bool modal,
17 const QString &caption,
18 int buttonMask, ButtonCode defaultButton,
19 bool separator,
20 const QString &user1,
21 const QString &user2,
22 const QString &user3) :
23 KDialog( parent, name, modal )
24{
25 init( caption, buttonMask, user1, user2 );
26 if (findButton( defaultButton ) )
27 (findButton( defaultButton ) )->setFocus();
28
29}
30
31KDialogBase::KDialogBase( int dialogFace, const QString &caption,
32 int buttonMask, ButtonCode defaultButton,
33 QWidget *parent, const char *name, bool modal,
34 bool separator,
35 const QString &user1,
36 const QString &user2,
37 const QString &user3) :
38 KDialog( parent, name, modal )
39{
40 init( caption, buttonMask, user1, user2 );
41 if (findButton( defaultButton ) )
42 (findButton( defaultButton ) )->setFocus();
43
44}
45
46KDialogBase::~KDialogBase()
47{
48}
49
50void KDialogBase::init( const QString &caption, int buttonMask,
51 const QString &user1 ,const QString &user2 )
52{
53 mMainWidget = 0;
54 mTabWidget = 0;
55 mPlainPage = 0;
56 mTopLayout = 0;
57 if ( !caption.isEmpty() ) {
58 setCaption( caption );
59 }
60
61 if ( buttonMask & User1 ) {
62 mUser1Button = new QPushButton( user1, this );
63 connect( mUser1Button, SIGNAL( clicked() ), SLOT( slotUser1() ) );
64 } else {
65 mUser1Button = 0;
66 }
67 if ( buttonMask & User2 ) {
68 mUser2Button = new QPushButton( user2, this );
69 connect( mUser2Button, SIGNAL( clicked() ), SLOT( slotUser2() ) );
70 } else {
71 mUser2Button = 0;
72 }
73
74 if ( buttonMask & Ok ) {
75 mOkButton = new QPushButton( i18n("Ok"), this );
76 connect( mOkButton, SIGNAL( clicked() ), SLOT( slotOk() ) );
77 } else {
78 mOkButton = 0;
79 }
80
81 if ( buttonMask & Apply ) {
82 mApplyButton = new QPushButton( i18n("Apply"), this );
83 connect( mApplyButton, SIGNAL( clicked() ), SLOT( slotApply() ) );
84 } else {
85 mApplyButton = 0;
86 }
87
88 if ( buttonMask & Cancel ) {
89 mCancelButton = new QPushButton( i18n("Cancel"), this );
90 connect( mCancelButton, SIGNAL( clicked() ), SLOT( slotCancel() ) );
91 } else {
92 mCancelButton = 0;
93 }
94
95 if ( buttonMask & Close ) {
96 mCloseButton = new QPushButton( i18n("Close"), this );
97 connect( mCloseButton, SIGNAL( clicked() ), SLOT( slotClose() ) );
98 } else {
99 mCloseButton = 0;
100 }
101}
102
103QTabWidget *KDialogBase::tabWidget()
104{
105 if ( !mTabWidget ) {
106 mTabWidget = new QTabWidget( this );
107 setMainWidget( mTabWidget );
108 }
109 return mTabWidget;
110}
111
112void KDialogBase::hideButtons()
113{
114 if ( mUser1Button ) mUser1Button->hide() ;
115 if ( mUser2Button ) mUser2Button->hide() ;
116 if ( mOkButton ) mOkButton->hide() ;
117 if ( mApplyButton ) mApplyButton->hide() ;
118 if ( mCancelButton ) mCancelButton->hide() ;
119 if ( mCloseButton ) mCloseButton->hide() ;
120
121}
122void KDialogBase::initLayout()
123{
124
125 delete mTopLayout;
126 mTopLayout = new QVBoxLayout( this );
127 mTopLayout->setMargin( marginHint() );
128 mTopLayout->setSpacing( spacingHint() );
129
130 mTopLayout->addWidget( mMainWidget );
131
132 QBoxLayout *buttonLayout = new QHBoxLayout;
133 mTopLayout->addLayout( buttonLayout );
134
135 if ( mUser1Button ) buttonLayout->addWidget( mUser1Button );
136 if ( mUser2Button ) buttonLayout->addWidget( mUser2Button );
137 if ( mOkButton ) buttonLayout->addWidget( mOkButton );
138 if ( mApplyButton ) buttonLayout->addWidget( mApplyButton );
139 if ( mCancelButton ) buttonLayout->addWidget( mCancelButton );
140 if ( mCloseButton ) buttonLayout->addWidget( mCloseButton );
141}
142
143QFrame *KDialogBase::addPage( const QString &name )
144{
145// kdDebug() << "KDialogBase::addPage(): " << name << endl;
146 QFrame *frame = new QFrame( tabWidget() );
147 tabWidget()->addTab( frame, name );
148 return frame;
149}
150
151QFrame *KDialogBase::addPage( const QString &name, int, const QPixmap & )
152{
153 return addPage( name );
154}
155
156
157void KDialogBase::setMainWidget( QWidget *widget )
158{
159 kdDebug() << "KDialogBase::setMainWidget()" << endl;
160
161 mMainWidget = widget;
162 initLayout();
163}
164
165void KDialogBase::setButtonText( ButtonCode id, const QString &text )
166{
167 QPushButton *button = findButton( id );
168 if ( button ) {
169 button->setText( text );
170 }
171}
172
173void KDialogBase::enableButton( ButtonCode id, bool state )
174{
175 QPushButton *button = findButton( id );
176 if ( button ) {
177 button->setEnabled( state );
178 }
179}
180
181QPushButton *KDialogBase::findButton( ButtonCode id )
182{
183 QPushButton *button = 0;
184 switch ( id ) {
185 case Ok:
186 button = mOkButton;
187 break;
188 case Apply:
189 button = mApplyButton;
190 break;
191 case User1:
192 button = mUser1Button;
193 break;
194 case User2:
195 button = mUser2Button;
196 break;
197 case Cancel:
198 button = mCancelButton;
199 break;
200 case Close:
201 button = mCloseButton;
202 break;
203 default:
204 break;
205 }
206 return button;
207}
208
209void KDialogBase::enableButtonOK( bool state )
210{
211 enableButton( Ok, state );
212}
213
214void KDialogBase::enableButtonApply( bool state )
215{
216 enableButton( Apply, state );
217}
218
219void KDialogBase::showButton( ButtonCode id, bool show )
220{
221 QPushButton *button = findButton( id );
222 if ( button ) {
223 if ( show ) button->show();
224 else button->hide();
225 }
226}
227
228int KDialogBase::pageIndex( QWidget *widget ) const
229{
230 return 0;
231}
232
233
234bool KDialogBase::showPage( int index )
235{
236 tabWidget()->setCurrentPage( index );return false;
237}
238
239QFrame *KDialogBase::plainPage()
240{
241 if ( !mPlainPage ) {
242 mPlainPage = new QFrame( this );
243 setMainWidget( mPlainPage );
244 }
245 return mPlainPage;
246}
247
248void KDialogBase::slotOk()
249{
250 emit okClicked();
251 accept();
252}
253
254void KDialogBase::slotApply()
255{
256 emit applyClicked();
257}
258
259void KDialogBase::slotCancel()
260{
261 emit cancelClicked();
262 reject();
263}
264
265void KDialogBase::slotClose()
266{
267 emit closeClicked();
268 reject();
269}
270
271void KDialogBase::slotUser1()
272{
273 emit user1Clicked();
274}
275void KDialogBase::slotUser2()
276{
277 emit user2Clicked();
278}
diff --git a/microkde/kdialogbase.h b/microkde/kdialogbase.h
new file mode 100644
index 0000000..199d2fa
--- a/dev/null
+++ b/microkde/kdialogbase.h
@@ -0,0 +1,139 @@
1#ifndef MINIKDE_KDIALOGBASE_H
2#define MINIKDE_KDIALOGBASE_H
3
4#include <qframe.h>
5
6#include "kdialog.h"
7
8class QPushButton;
9class QLayout;
10class QTabWidget;
11class QBoxLayout;
12
13class KDialogBase : public KDialog
14{
15 Q_OBJECT
16 public:
17 enum ButtonCode
18 {
19 Help = 0x00000001,
20 Default = 0x00000002,
21 Ok = 0x00000004,
22 Apply = 0x00000008,
23 Try = 0x00000010,
24 Cancel = 0x00000020,
25 Close = 0x00000040,
26 User1 = 0x00000080,
27 User2 = 0x00000100,
28 User3 = 0x00000200,
29 No = 0x00000080,
30 Yes = 0x00000100,
31 Details = 0x00000400,
32 Filler = 0x40000000,
33 Stretch = 0x80000000
34 };
35
36 enum DialogType
37 {
38 TreeList,
39 Tabbed,
40 Plain,
41 Swallow,
42 IconList
43 };
44
45 KDialogBase();
46 KDialogBase( QWidget *parent=0, const char *name=0, bool modal=true,
47 const QString &caption=QString::null,
48 int buttonMask=Ok|Apply|Cancel, ButtonCode defaultButton=Ok,
49 bool separator=false,
50 const QString &user1=QString::null,
51 const QString &user2=QString::null,
52 const QString &user3=QString::null);
53 KDialogBase( int dialogFace, const QString &caption,
54 int buttonMask, ButtonCode defaultButton,
55 QWidget *parent=0, const char *name=0, bool modal=true,
56 bool separator=false,
57 const QString &user1=QString::null,
58 const QString &user2=QString::null,
59 const QString &user3=QString::null);
60 virtual ~KDialogBase();
61
62 QFrame *addPage( const QString & );
63 QFrame *addPage( const QString &, int, const QPixmap & );
64
65 void setMainWidget( QWidget *widget );
66
67 void setButtonText( ButtonCode id, const QString &text );
68
69 void enableButton( ButtonCode id, bool state );
70 void enableButtonOK( bool state );
71 void enableButtonApply( bool state );
72
73 void showButton( ButtonCode, bool show );
74
75 int pageIndex( QWidget *widget ) const;
76
77 bool showPage( int index );
78 void hideButtons();
79
80 QFrame *plainPage();
81
82 signals:
83 void user1Clicked();
84 void user2Clicked();
85 /**
86 * The Apply button was pressed. This signal is only emitted if
87 * @ref slotApply() is not replaced.
88 */
89 void applyClicked();
90
91 /**
92 * The OK button was pressed. This signal is only emitted if
93 * @ref slotOk() is not replaced.
94 */
95 void okClicked();
96
97 /**
98 * The Cancel button was pressed. This signal is only emitted if
99 * @ref slotCancel() is not replaced.
100 */
101 void cancelClicked();
102
103 /**
104 * The Close button was pressed. This signal is only emitted if
105 * @ref slotClose() is not replaced.
106 */
107 void closeClicked();
108
109 protected slots:
110 virtual void slotOk();
111 virtual void slotApply();
112 virtual void slotCancel();
113 virtual void slotClose();
114 virtual void slotUser1();
115 virtual void slotUser2();
116
117 protected:
118 QPushButton *findButton( ButtonCode );
119
120 private:
121 QTabWidget *tabWidget();
122 void init( const QString &caption, int buttonMask,
123 const QString &user1=QString::null, const QString &user2=QString::null );
124 void initLayout();
125
126 QWidget *mMainWidget;
127 QTabWidget *mTabWidget;
128 QFrame *mPlainPage;
129 QBoxLayout *mTopLayout;
130
131 QPushButton *mUser1Button;
132 QPushButton *mUser2Button;
133 QPushButton *mCloseButton;
134 QPushButton *mOkButton;
135 QPushButton *mApplyButton;
136 QPushButton *mCancelButton;
137};
138
139#endif
diff --git a/microkde/kdirwatch.h b/microkde/kdirwatch.h
new file mode 100644
index 0000000..22b4dec
--- a/dev/null
+++ b/microkde/kdirwatch.h
@@ -0,0 +1,14 @@
1#ifndef MICROKDE_KDIRWATCH_H
2#define MICROKDE_KDIRWATCH_H
3
4#include <qobject.h>
5
6class KDirWatch : public QObject
7{
8 public:
9 KDirWatch() {}
10
11 void addDir( const QString & ) {}
12};
13
14#endif
diff --git a/microkde/keditlistbox.cpp b/microkde/keditlistbox.cpp
new file mode 100644
index 0000000..55b7784
--- a/dev/null
+++ b/microkde/keditlistbox.cpp
@@ -0,0 +1,389 @@
1/* This file is part of the KDE libraries
2 Copyright (C) 2000 David Faure <faure@kde.org>, Alexander Neundorf <neundorf@kde.org>
3 2000, 2002 Carsten Pfeiffer <pfeiffer@kde.org>
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21#include <qstringlist.h>
22#include <qpushbutton.h>
23#include <qlayout.h>
24#include <qgroupbox.h>
25#include <qlistbox.h>
26#include <qwhatsthis.h>
27#include <qlabel.h>
28
29#include <kcombobox.h>
30#include <kdebug.h>
31#include <kdialog.h>
32#include <klineedit.h>
33#include <klocale.h>
34#include <kapplication.h>
35#include <knotifyclient.h>
36
37#include "keditlistbox.h"
38
39#include <assert.h>
40
41class KEditListBoxPrivate
42{
43public:
44 bool m_checkAtEntering;
45 int buttons;
46};
47
48KEditListBox::KEditListBox(QWidget *parent, const char *name,
49 bool checkAtEntering, int buttons )
50 :QGroupBox(parent, name )
51{
52 init( checkAtEntering, buttons );
53}
54
55KEditListBox::KEditListBox(const QString& title, QWidget *parent,
56 const char *name, bool checkAtEntering, int buttons)
57 :QGroupBox(title, parent, name )
58{
59 init( checkAtEntering, buttons );
60}
61
62KEditListBox::KEditListBox(const QString& title, const CustomEditor& custom,
63 QWidget *parent, const char *name,
64 bool checkAtEntering, int buttons)
65 :QGroupBox(title, parent, name )
66{
67 m_lineEdit = custom.lineEdit();
68 init( checkAtEntering, buttons, custom.representationWidget() );
69}
70
71KEditListBox::~KEditListBox()
72{
73 delete d;
74 d=0;
75}
76
77void KEditListBox::init( bool checkAtEntering, int buttons,
78 QWidget *representationWidget )
79{
80 d=new KEditListBoxPrivate;
81 d->m_checkAtEntering=checkAtEntering;
82 d->buttons = buttons;
83
84 int lostButtons = 0;
85 if ( (buttons & Add) == 0 )
86 lostButtons++;
87 if ( (buttons & Remove) == 0 )
88 lostButtons++;
89 if ( (buttons & UpDown) == 0 )
90 lostButtons += 2;
91
92
93 servNewButton = servRemoveButton = servUpButton = servDownButton = 0L;
94 setSizePolicy(QSizePolicy(QSizePolicy::MinimumExpanding,
95 QSizePolicy::MinimumExpanding));
96
97 QWidget * gb = this;
98 QGridLayout * grid = new QGridLayout(gb, 7 - lostButtons, 2,
99 KDialog::marginHint(),
100 KDialog::spacingHint());
101 grid->addRowSpacing(0, fontMetrics().lineSpacing());
102 for ( int i = 1; i < 7 - lostButtons; i++ )
103 grid->setRowStretch(i, 1);
104
105 grid->setMargin(15);
106
107 if ( representationWidget )
108 representationWidget->reparent( gb, QPoint(0,0) );
109 else
110 m_lineEdit=new KLineEdit(gb);
111
112 m_listBox = new QListBox(gb);
113
114 QWidget *editingWidget = representationWidget ?
115 representationWidget : m_lineEdit;
116 grid->addMultiCellWidget(editingWidget,1,1,0,1);
117 grid->addMultiCellWidget(m_listBox, 2, 6 - lostButtons, 0, 0);
118 int row = 2;
119 if ( buttons & Add ) {
120 servNewButton = new QPushButton(i18n("&Add"), gb);
121 servNewButton->setEnabled(false);
122 connect(servNewButton, SIGNAL(clicked()), SLOT(addItem()));
123
124 grid->addWidget(servNewButton, row++, 1);
125 }
126
127 if ( buttons & Remove ) {
128 servRemoveButton = new QPushButton(i18n("&Remove"), gb);
129 servRemoveButton->setEnabled(false);
130 connect(servRemoveButton, SIGNAL(clicked()), SLOT(removeItem()));
131
132 grid->addWidget(servRemoveButton, row++, 1);
133 }
134
135 if ( buttons & UpDown ) {
136 servUpButton = new QPushButton(i18n("Move &Up"), gb);
137 servUpButton->setEnabled(false);
138 connect(servUpButton, SIGNAL(clicked()), SLOT(moveItemUp()));
139
140 servDownButton = new QPushButton(i18n("Move &Down"), gb);
141 servDownButton->setEnabled(false);
142 connect(servDownButton, SIGNAL(clicked()), SLOT(moveItemDown()));
143
144 grid->addWidget(servUpButton, row++, 1);
145 grid->addWidget(servDownButton, row++, 1);
146 }
147
148 connect(m_lineEdit,SIGNAL(textChanged(const QString&)),this,SLOT(typedSomething(const QString&)));
149 m_lineEdit->setTrapReturnKey(true);
150 connect(m_lineEdit,SIGNAL(returnPressed()),this,SLOT(addItem()));
151 connect(m_listBox, SIGNAL(highlighted(int)), SLOT(enableMoveButtons(int)));
152
153 // maybe supplied lineedit has some text already
154 typedSomething( m_lineEdit->text() );
155}
156
157void KEditListBox::typedSomething(const QString& text)
158{
159 if(currentItem() >= 0) {
160 if(currentText() != m_lineEdit->text())
161 {
162 // IMHO changeItem() shouldn't do anything with the value
163 // of currentItem() ... like changing it or emitting signals ...
164 // but TT disagree with me on this one (it's been that way since ages ... grrr)
165 bool block = m_listBox->signalsBlocked();
166 m_listBox->blockSignals( true );
167 m_listBox->changeItem(text, currentItem());
168 m_listBox->blockSignals( block );
169 emit changed();
170 }
171 }
172
173 if ( !servNewButton )
174 return;
175
176 if (!d->m_checkAtEntering)
177 servNewButton->setEnabled(!text.isEmpty());
178 else
179 {
180 if (text.isEmpty())
181 {
182 servNewButton->setEnabled(false);
183 }
184 else
185 {
186 bool enable = (m_listBox->findItem( text ) == 0L);
187 servNewButton->setEnabled( enable );
188 }
189 }
190}
191
192void KEditListBox::moveItemUp()
193{
194 if (!m_listBox->isEnabled())
195 {
196 KNotifyClient::beep();
197 return;
198 }
199
200 unsigned int selIndex = m_listBox->currentItem();
201 if (selIndex == 0)
202 {
203 KNotifyClient::beep();
204 return;
205 }
206
207 QListBoxItem *selItem = m_listBox->item(selIndex);
208 m_listBox->takeItem(selItem);
209 m_listBox->insertItem(selItem, selIndex-1);
210 m_listBox->setCurrentItem(selIndex - 1);
211
212 emit changed();
213}
214
215void KEditListBox::moveItemDown()
216{
217 if (!m_listBox->isEnabled())
218 {
219 KNotifyClient::beep();
220 return;
221 }
222
223 unsigned int selIndex = m_listBox->currentItem();
224 if (selIndex == m_listBox->count() - 1)
225 {
226 KNotifyClient::beep();
227 return;
228 }
229
230 QListBoxItem *selItem = m_listBox->item(selIndex);
231 m_listBox->takeItem(selItem);
232 m_listBox->insertItem(selItem, selIndex+1);
233 m_listBox->setCurrentItem(selIndex + 1);
234
235 emit changed();
236}
237
238void KEditListBox::addItem()
239{
240 // when m_checkAtEntering is true, the add-button is disabled, but this
241 // slot can still be called through Key_Return/Key_Enter. So we guard
242 // against this.
243 if ( !servNewButton || !servNewButton->isEnabled() )
244 return;
245
246 const QString& currentTextLE=m_lineEdit->text();
247 bool alreadyInList(false);
248 //if we didn't check for dupes at the inserting we have to do it now
249 if (!d->m_checkAtEntering)
250 {
251 // first check current item instead of dumb iterating the entire list
252 if ( m_listBox->currentText() == currentTextLE )
253 alreadyInList = true;
254 else
255 {
256 alreadyInList =(m_listBox->findItem(currentTextLE) != 0);
257 }
258 }
259
260 if ( servNewButton )
261 servNewButton->setEnabled(false);
262
263 bool block = m_lineEdit->signalsBlocked();
264 m_lineEdit->blockSignals(true);
265 m_lineEdit->clear();
266 m_lineEdit->blockSignals(block);
267
268 m_listBox->setSelected(currentItem(), false);
269
270 if (!alreadyInList)
271 {
272 block = m_listBox->signalsBlocked();
273 m_listBox->blockSignals( true );
274 m_listBox->insertItem(currentTextLE);
275 m_listBox->blockSignals( block );
276 emit changed();
277 }
278}
279
280int KEditListBox::currentItem() const
281{
282 int nr = m_listBox->currentItem();
283 if(nr >= 0 && !m_listBox->item(nr)->selected()) return -1;
284 return nr;
285}
286
287void KEditListBox::removeItem()
288{
289 int selected = m_listBox->currentItem();
290
291 if ( selected >= 0 )
292 {
293 m_listBox->removeItem( selected );
294 if ( count() > 0 )
295 m_listBox->setSelected( QMIN( selected, count() - 1 ), true );
296
297 emit changed();
298 }
299
300 if ( servRemoveButton && m_listBox->currentItem() == -1 )
301 servRemoveButton->setEnabled(false);
302}
303
304void KEditListBox::enableMoveButtons(int index)
305{
306 // Update the lineEdit when we select a different line.
307 if(currentText() != m_lineEdit->text())
308 m_lineEdit->setText(currentText());
309
310 bool moveEnabled = servUpButton && servDownButton;
311
312 if (moveEnabled )
313 {
314 if (m_listBox->count() <= 1)
315 {
316 servUpButton->setEnabled(false);
317 servDownButton->setEnabled(false);
318 }
319 else if ((uint) index == (m_listBox->count() - 1))
320 {
321 servUpButton->setEnabled(true);
322 servDownButton->setEnabled(false);
323 }
324 else if (index == 0)
325 {
326 servUpButton->setEnabled(false);
327 servDownButton->setEnabled(true);
328 }
329 else
330 {
331 servUpButton->setEnabled(true);
332 servDownButton->setEnabled(true);
333 }
334 }
335
336 if ( servRemoveButton )
337 servRemoveButton->setEnabled(true);
338}
339
340void KEditListBox::clear()
341{
342 m_lineEdit->clear();
343 m_listBox->clear();
344 emit changed();
345}
346
347void KEditListBox::insertStringList(const QStringList& list, int index)
348{
349 m_listBox->insertStringList(list,index);
350}
351
352void KEditListBox::insertStrList(const QStrList* list, int index)
353{
354 m_listBox->insertStrList(list,index);
355}
356
357void KEditListBox::insertStrList(const QStrList& list, int index)
358{
359 m_listBox->insertStrList(list,index);
360}
361
362void KEditListBox::insertStrList(const char ** list, int numStrings, int index)
363{
364 m_listBox->insertStrList(list,numStrings,index);
365}
366
367QStringList KEditListBox::items() const
368{
369 QStringList list;
370 for ( uint i = 0; i < m_listBox->count(); i++ )
371 list.append( m_listBox->text( i ));
372
373 return list;
374}
375
376void KEditListBox::virtual_hook( int, void* )
377{ /*BASE::virtual_hook( id, data );*/ }
378
379
380///////////////////////////////////////////////////////////////////
381///////////////////////////////////////////////////////////////////
382
383KEditListBox::CustomEditor::CustomEditor( KComboBox *combo )
384{
385 m_representationWidget = combo;
386 m_lineEdit = static_cast<KLineEdit*>( combo->lineEdit() );
387 assert( m_lineEdit );
388}
389
diff --git a/microkde/keditlistbox.h b/microkde/keditlistbox.h
new file mode 100644
index 0000000..130d933
--- a/dev/null
+++ b/microkde/keditlistbox.h
@@ -0,0 +1,226 @@
1/* This file is part of the KDE libraries
2 Copyright (C) 2000 David Faure <faure@kde.org>, Alexander Neundorf <neundorf@kde.org>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA.
18*/
19
20#ifndef KEDITLISTBOX_H
21#define KEDITLISTBOX_H
22
23#include <qgroupbox.h>
24#include <qlistbox.h>
25
26class KLineEdit;
27class KComboBox;
28class QPushButton;
29
30class KEditListBoxPrivate;
31/**
32 * An editable listbox
33 *
34 * This class provides a editable listbox ;-), this means
35 * a listbox which is accompanied by a line edit to enter new
36 * items into the listbox and pushbuttons to add and remove
37 * items from the listbox and two buttons to move items up and down.
38 */
39class KEditListBox : public QGroupBox
40{
41 Q_OBJECT
42
43public:
44 /// @since 3.1
45 class CustomEditor
46 {
47 public:
48 CustomEditor()
49 : m_representationWidget( 0L ),
50 m_lineEdit( 0L ) {}
51 CustomEditor( QWidget *repWidget, KLineEdit *edit )
52 : m_representationWidget( repWidget ),
53 m_lineEdit( edit ) {}
54 CustomEditor( KComboBox *combo );
55
56 void setRepresentationWidget( QWidget *repWidget ) {
57 m_representationWidget = repWidget;
58 }
59 void setLineEdit( KLineEdit *edit ) {
60 m_lineEdit = edit;
61 }
62
63 virtual QWidget *representationWidget() const {
64 return m_representationWidget;
65 }
66 virtual KLineEdit *lineEdit() const {
67 return m_lineEdit;
68 }
69
70 protected:
71 QWidget *m_representationWidget;
72 KLineEdit *m_lineEdit;
73 };
74
75 public:
76
77 /**
78 * Enumeration of the buttons, the listbox offers. Specify them in the
79 * constructor in the buttons parameter.
80 */
81 enum Button { Add = 1, Remove = 2, UpDown = 4, All = Add|Remove|UpDown };
82
83 /**
84 * Create an editable listbox.
85 *
86 * If @p checkAtEntering is true, after every character you type
87 * in the line edit KEditListBox will enable or disable
88 * the Add-button, depending whether the current content of the
89 * line edit is already in the listbox. Maybe this can become a
90 * performance hit with large lists on slow machines.
91 * If @p checkAtEntering is false,
92 * it will be checked if you press the Add-button. It is not
93 * possible to enter items twice into the listbox.
94 */
95 KEditListBox(QWidget *parent = 0, const char *name = 0,
96 bool checkAtEntering=false, int buttons = All );
97 /**
98 * Create an editable listbox.
99 *
100 * The same as the other constructor, additionally it takes
101 * @title, which will be the title of the frame around the listbox.
102 */
103 KEditListBox(const QString& title, QWidget *parent = 0,
104 const char *name = 0, bool checkAtEntering=false,
105 int buttons = All );
106
107 /**
108 * Another constructor, which allows to use a custom editing widget
109 * instead of the standard KLineEdit widget. E.g. you can use a
110 * @ref KURLRequester or a @ref KComboBox as input widget. The custom
111 * editor must consist of a lineedit and optionally another widget that
112 * is used as representation. A KComboBox or a KURLRequester have a
113 * KLineEdit as child-widget for example, so the KComboBox is used as
114 * the representation widget.
115 *
116 * @see KURLRequester::customEditor()
117 * @since 3.1
118 */
119 KEditListBox( const QString& title,
120 const CustomEditor &customEditor,
121 QWidget *parent = 0, const char *name = 0,
122 bool checkAtEntering = false, int buttons = All );
123
124 virtual ~KEditListBox();
125
126 /**
127 * Return a pointer to the embedded QListBox.
128 */
129 QListBox* listBox() const { return m_listBox; }
130 /**
131 * Return a pointer to the embedded QLineEdit.
132 */
133 KLineEdit* lineEdit() const { return m_lineEdit; }
134 /**
135 * Return a pointer to the Add button
136 */
137 QPushButton* addButton() const { return servNewButton; }
138 /**
139 * Return a pointer to the Remove button
140 */
141 QPushButton* removeButton() const { return servRemoveButton; }
142 /**
143 * Return a pointer to the Up button
144 */
145 QPushButton* upButton() const { return servUpButton; }
146 /**
147 * Return a pointer to the Down button
148 */
149 QPushButton* downButton() const { return servDownButton; }
150
151 /**
152 * See @ref QListBox::count()
153 */
154 int count() const { return int(m_listBox->count()); }
155 /**
156 * See @ref QListBox::insertStringList()
157 */
158 void insertStringList(const QStringList& list, int index=-1);
159 /**
160 * See @ref QListBox::insertStringList()
161 */
162 void insertStrList(const QStrList* list, int index=-1);
163 /**
164 * See @ref QListBox::insertStrList()
165 */
166 void insertStrList(const QStrList& list, int index=-1);
167 /**
168 * See @ref QListBox::insertStrList()
169 */
170 void insertStrList(const char ** list, int numStrings=-1, int index=-1);
171 /**
172 * See @ref QListBox::insertItem()
173 */
174 void insertItem(const QString& text, int index=-1) {m_listBox->insertItem(text,index);}
175 /**
176 * Clears both the listbox and the line edit.
177 */
178 void clear();
179 /**
180 * See @ref QListBox::text()
181 */
182 QString text(int index) const { return m_listBox->text(index); }
183 /**
184 * See @ref QListBox::currentItem()
185 */
186 int currentItem() const;
187 /**
188 * See @ref QListBox::currentText()
189 */
190 QString currentText() const { return m_listBox->currentText(); }
191
192 /**
193 * @returns a stringlist of all items in the listbox
194 */
195 QStringList items() const;
196
197 signals:
198 void changed();
199
200 protected slots:
201 //the names should be self-explaining
202 void moveItemUp();
203 void moveItemDown();
204 void addItem();
205 void removeItem();
206 void enableMoveButtons(int index);
207 void typedSomething(const QString& text);
208
209 private:
210 QListBox *m_listBox;
211 QPushButton *servUpButton, *servDownButton;
212 QPushButton *servNewButton, *servRemoveButton;
213 KLineEdit *m_lineEdit;
214
215 //this is called in both ctors, to avoid code duplication
216 void init( bool checkAtEntering, int buttons,
217 QWidget *representationWidget = 0L );
218
219 protected:
220 virtual void virtual_hook( int id, void* data );
221 private:
222 //our lovely private d-pointer
223 KEditListBoxPrivate *d;
224};
225
226#endif
diff --git a/microkde/kemailsettings.cpp b/microkde/kemailsettings.cpp
new file mode 100644
index 0000000..9a9ad84
--- a/dev/null
+++ b/microkde/kemailsettings.cpp
@@ -0,0 +1,6 @@
1#include "kemailsettings.h"
2
3QString KEMailSettings::getSetting(KEMailSettings::Setting s)
4{
5 return QString::null;
6}
diff --git a/microkde/kemailsettings.h b/microkde/kemailsettings.h
new file mode 100644
index 0000000..cf43f17
--- a/dev/null
+++ b/microkde/kemailsettings.h
@@ -0,0 +1,32 @@
1#ifndef MINIKDE_KEMAILSETTINGS_H
2#define MINIKDE_KEMAILSETTINGS_H
3
4#include <qstring.h>
5
6class KEMailSettings
7{
8 public:
9 enum Setting {
10 ClientProgram,
11 ClientTerminal,
12 RealName,
13 EmailAddress,
14 ReplyToAddress,
15 Organization,
16 OutServer,
17 OutServerLogin,
18 OutServerPass,
19 OutServerType,
20 OutServerCommand,
21 OutServerTLS,
22 InServer,
23 InServerLogin,
24 InServerPass,
25 InServerType,
26 InServerMBXType,
27 InServerTLS
28 };
29 QString getSetting(KEMailSettings::Setting s);
30};
31
32#endif
diff --git a/microkde/kfiledialog.cpp b/microkde/kfiledialog.cpp
new file mode 100644
index 0000000..977499e
--- a/dev/null
+++ b/microkde/kfiledialog.cpp
@@ -0,0 +1,74 @@
1#include <kfiledialog.h>
2#include <qdialog.h>
3#include <qlayout.h>
4#include <qdir.h>
5#include <qfileinfo.h>
6#include <qapplication.h>
7
8#ifndef DESKTOP_VERSION
9//US orig#include <ofileselector.h>
10#include <ofileselector_p.h>
11QString KFileDialog::getSaveFileName( const QString & fn,
12 const QString & cap , QWidget * par )
13{
14 QString retfile = "";
15 QDialog dia ( par, "input-dialog", true );
16 QVBoxLayout lay( &dia );
17 lay.setMargin(7);
18 lay.setSpacing(7);
19 dia.setCaption( cap );
20 QString file = fn;
21 if ( file.isEmpty() )
22 file = QDir::homeDirPath()+"/*";
23 QFileInfo fi ( file );
24 OFileSelector o ( &dia,OFileSelector::FileSelector, OFileSelector::Save, fi.dirPath(true), fi.fileName() );
25 lay.addWidget( &o);
26 // o.setNewVisible( true );
27 // o.setNameVisible( true );
28 dia.showMaximized();
29 int res = dia.exec();
30 if ( res )
31 retfile = o.selectedName();
32 return retfile;
33}
34
35QString KFileDialog::getOpenFileName( const QString & fn,
36 const QString & cap, QWidget * par )
37{
38 QString retfile = "";
39 QDialog dia ( par, "input-dialog", true );
40 // QLineEdit lab ( &dia );
41 QVBoxLayout lay( &dia );
42 lay.setMargin(7);
43 lay.setSpacing(7);
44 dia.setCaption( cap );
45 QString file = fn;
46 if ( file.isEmpty() )
47 file = QDir::homeDirPath()+"/*";;
48 QFileInfo fi ( file );
49 OFileSelector o ( &dia,OFileSelector::FileSelector, OFileSelector::Open, fi.dirPath(true), fi.fileName() );
50 lay.addWidget( &o);
51 dia.showMaximized();
52 int res = dia.exec();
53 if ( res )
54 retfile = o.selectedName();
55 return retfile;
56}
57
58#else
59
60#include <qfiledialog.h>
61
62QString KFileDialog::getSaveFileName( const QString & fn,
63 const QString & cap , QWidget * par )
64{
65 return QFileDialog::getSaveFileName( fn, QString::null, par, "openfile", cap );
66}
67QString KFileDialog::getOpenFileName( const QString & fn,
68 const QString & cap, QWidget * par )
69{
70
71 return QFileDialog::getOpenFileName( fn, QString::null, par, "openfile", cap );
72}
73#endif
74
diff --git a/microkde/kfiledialog.h b/microkde/kfiledialog.h
new file mode 100644
index 0000000..0825872
--- a/dev/null
+++ b/microkde/kfiledialog.h
@@ -0,0 +1,20 @@
1#ifndef MICROKDE_KFILEDIALOG_H
2#define MICROKDE_KFILEDIALOG_H
3
4#include <qstring.h>
5#include <qwidget.h>
6
7class KFileDialog
8{
9 public:
10
11 static QString getSaveFileName( const QString &,
12 const QString &, QWidget * );
13
14
15 static QString getOpenFileName( const QString &,
16 const QString &, QWidget * );
17
18};
19
20#endif
diff --git a/microkde/kfontdialog.cpp b/microkde/kfontdialog.cpp
new file mode 100644
index 0000000..174123c
--- a/dev/null
+++ b/microkde/kfontdialog.cpp
@@ -0,0 +1,32 @@
1#include "kfontdialog.h"
2#ifndef DESKTOP_VERSION
3#include "ofontselector.h"
4#else
5#include <qfontdialog.h>
6#endif
7#include <qdialog.h>
8#include <qlayout.h>
9#include <qpushbutton.h>
10QFont KFontDialog::getFont( const QFont & f, bool & ok )
11{
12#ifndef DESKTOP_VERSION
13 QDialog d( 0, "fd", true );;
14 OFontSelector s ( true, &d, "fontsel");
15 QVBoxLayout l ( &d );
16 l.addWidget( &s );
17 s.setSelectedFont ( f );
18 QPushButton b ( "OK", &d );
19 l.addWidget( &b );
20 qDebug("size %d ", f.bold());
21 QObject::connect( &b, SIGNAL( clicked () ), &d, SLOT ( accept () ) );
22 d.show();
23 ok = false;
24 if ( d.exec () ) {
25 ok = true;
26 return s.selectedFont ( );
27 }
28 return f;
29#else
30 return QFontDialog::getFont ( &ok, f, 0, "fontdialog" );
31#endif
32}
diff --git a/microkde/kfontdialog.h b/microkde/kfontdialog.h
new file mode 100644
index 0000000..f2ac6ac
--- a/dev/null
+++ b/microkde/kfontdialog.h
@@ -0,0 +1,15 @@
1#ifndef MINIKDE_KFONTDIALOG_H
2#define MINIKDE_KFONTDIALOG_H
3
4#include <qfont.h>
5#include <qdialog.h>
6
7class KFontDialog
8{
9 public:
10 enum { Accepted };
11
12 static QFont getFont( const QFont & f, bool & ok);
13};
14
15#endif
diff --git a/microkde/kglobal.cpp b/microkde/kglobal.cpp
new file mode 100644
index 0000000..0aba952
--- a/dev/null
+++ b/microkde/kglobal.cpp
@@ -0,0 +1,166 @@
1#include "kglobal.h"
2#include <qkeycode.h>
3#include <qapplication.h>
4
5KLocale *KGlobal::mLocale = 0;
6KConfig *KGlobal::mConfig = 0;
7KIconLoader *KGlobal::mIconLoader = 0;
8KStandardDirs *KGlobal::mDirs = 0;
9
10QString KGlobal::mAppName = "godot";
11
12KLocale *KGlobal::locale()
13{
14 if ( !mLocale ) {
15 ASSERT(mAppName);
16
17 mLocale = new KLocale();//mAppName);
18 }
19
20 return mLocale;
21}
22
23//US
24void KGlobal::setLocale(KLocale *kg)
25{
26 mLocale = kg;
27}
28
29KConfig *KGlobal::config()
30{
31 if ( !mConfig ) {
32 mConfig = new KConfig( KStandardDirs::appDir() + mAppName + "rc" );
33 }
34
35 return mConfig;
36}
37
38KGlobal::Size KGlobal::getDesktopSize()
39{
40#ifdef DESKTOP_VERSION
41 return KGlobal::Desktop;
42#else
43 if ( QApplication::desktop()->width() < 480 )
44 return KGlobal::Small;
45 else
46 return KGlobal::Medium;
47#endif
48}
49
50KGlobal::Orientation KGlobal::getOrientation()
51{
52 if (QApplication::desktop()->width() > QApplication::desktop()->height())
53 return KGlobal::Landscape;
54 else
55 return KGlobal::Portrait;
56}
57
58int KGlobal::getDesktopWidth()
59{
60 return QApplication::desktop()->width();
61}
62
63int KGlobal::getDesktopHeight()
64{
65 return QApplication::desktop()->height();
66}
67
68
69KIconLoader *KGlobal::iconLoader()
70{
71 if ( !mIconLoader ) {
72 mIconLoader = new KIconLoader();
73 }
74
75 return mIconLoader;
76}
77
78KStandardDirs *KGlobal::dirs()
79{
80 if ( !mDirs ) {
81 mDirs = new KStandardDirs();
82 }
83
84 return mDirs;
85}
86
87void KGlobal::setAppName( const QString &appName )
88{
89 mAppName = appName;
90}
91
92//US
93QString KGlobal::getAppName()
94{
95 return mAppName;
96}
97QString KGlobal::formatMessage ( QString mess, int maxlen )
98{
99 //int maxlen = 80;
100 int start = 0;
101 int end = mess.length();
102 QString retVal = "";
103 int nl, space;
104 while ( (end - start) > maxlen ) {
105 nl = mess.find( "\n", start );
106 if ( nl > 0 && nl < start + maxlen ) {
107 nl += 1;
108 retVal += mess.mid( start, nl - start);
109 start = nl;
110 } else {
111 space = mess.findRev( " ", start + maxlen );
112 if ( space < start ) {
113 retVal += mess.mid( start, maxlen) +"\n";
114 start += maxlen ;
115 } else {
116 retVal += mess.mid( start, space - start ) +"\n";
117 start = space+ 1;
118 }
119 }
120 }
121 retVal += mess.mid( start, end - start );
122 return retVal;
123}
124int KGlobal::knumkeykonv( int k )
125{
126 int key;
127switch( k ) {
128 case Qt::Key_Q :
129 key = Qt::Key_1;
130 break;
131 case Qt::Key_W :
132 key = Qt::Key_2;
133 break;
134 case Qt::Key_E :
135 key = Qt::Key_3;
136 break;
137 case Qt::Key_R :
138 key = Qt::Key_4;
139 break;
140 case Qt::Key_T :
141 key = Qt::Key_5;
142 break;
143 case Qt::Key_Z :
144 key = Qt::Key_6;
145 break;
146 case Qt::Key_Y :
147 key = Qt::Key_6;
148 break;
149 case Qt::Key_U :
150 key = Qt::Key_7;
151 break;
152 case Qt::Key_I :
153 key = Qt::Key_8;
154 break;
155 case Qt::Key_O :
156 key = Qt::Key_9;
157 break;
158 case Qt::Key_P :
159 key = Qt::Key_0;
160 break;
161 default:
162 key = k;
163 break;
164 } // switch
165 return key;
166}
diff --git a/microkde/kglobal.h b/microkde/kglobal.h
new file mode 100644
index 0000000..1e03bea
--- a/dev/null
+++ b/microkde/kglobal.h
@@ -0,0 +1,68 @@
1#ifndef MINIKDE_KGLOBAL_H
2#define MINIKDE_KGLOBAL_H
3
4#include "klocale.h"
5#include "kconfig.h"
6#include "kiconloader.h"
7#include <kstandarddirs.h>
8#include <qevent.h>
9class KStandardDirs;
10class KGlobal {
11 public:
12 static KLocale *locale();
13 static KConfig *config();
14 static KIconLoader *iconLoader();
15 static KStandardDirs *dirs();
16 static int knumkeykonv( int );
17
18 static void setAppName( const QString & );
19 static QString formatMessage( QString mess, int maxlen ) ;
20
21//US begin: added the following methods for convenience
22 static QString getAppName();
23 static void setLocale(KLocale *);
24
25 enum Orientation { Portrait, Landscape };
26 enum Size { Small, Medium, Desktop };
27
28 static int getDesktopWidth();
29 static int getDesktopHeight();
30 static KGlobal::Size getDesktopSize();
31 static KGlobal::Orientation getOrientation();
32
33
34 private:
35 static KLocale *mLocale;
36 static KConfig *mConfig;
37 static KIconLoader *mIconLoader;
38 static KStandardDirs *mDirs;
39
40 static QString mAppName;
41};
42
43
44/** @ref KGlobal
45 * A typesafe function to find the minimum of the two arguments.
46 */
47 #define KMIN(a,b)kMin(a,b)
48/** @ref KGlobal
49 * A typesafe function to find the maximum of the two arguments.
50 */
51 #define KMAX(a,b)kMax(a,b)
52/** @ref KGlobal
53 * A typesafe function to determine the absolute value of the argument.
54 */
55 #define KABS(a)kAbs(a)
56
57
58template<class T>
59inline const T& kMin (const T& a, const T& b) { return a < b ? a : b; }
60
61template<class T>
62inline const T& kMax (const T& a, const T& b) { return b < a ? a : b; }
63
64template<class T>
65inline T kAbs (const T& a) { return a < 0 ? -a : a; }
66
67
68#endif
diff --git a/microkde/kglobalsettings.cpp b/microkde/kglobalsettings.cpp
new file mode 100644
index 0000000..2fff8fc
--- a/dev/null
+++ b/microkde/kglobalsettings.cpp
@@ -0,0 +1,41 @@
1#include "kglobalsettings.h"
2#include "kconfig.h"
3#include "kglobal.h"
4#include "kconfigbase.h"
5
6#include <qapplication.h>
7
8QFont KGlobalSettings::generalFont()
9{
10 int size = 12;
11 if (QApplication::desktop()->width() < 480 )
12 size = 10;
13 return QFont("helvetica",size);
14}
15QFont KGlobalSettings::toolBarFont()
16{
17 return QFont("helevetica",12);
18}
19
20QColor KGlobalSettings::toolBarHighlightColor()
21{
22 return QColor("black");
23}
24
25QRect KGlobalSettings::desktopGeometry( QWidget * )
26{
27 return QApplication::desktop()->rect();
28}
29
30 /**
31 * Returns whether KDE runs in single (default) or double click
32 * mode.
33 * see http://developer.kde.org/documentation/standards/kde/style/mouse/index.html
34 * @return true if single click mode, or false if double click mode.
35 **/
36bool KGlobalSettings::singleClick()
37{
38 KConfig *c = KGlobal::config();
39 KConfigGroupSaver cgs( c, "KDE" );
40 return c->readBoolEntry("SingleClick", KDE_DEFAULT_SINGLECLICK);
41}
diff --git a/microkde/kglobalsettings.h b/microkde/kglobalsettings.h
new file mode 100644
index 0000000..7df8012
--- a/dev/null
+++ b/microkde/kglobalsettings.h
@@ -0,0 +1,30 @@
1#ifndef MICROKDE_KGLOBALSETTINGS_H
2#define MICROKDE_KGLOBALSETTINGS_H
3
4#include <qfont.h>
5#include <qrect.h>
6
7
8#define KDE_DEFAULT_SINGLECLICK true
9
10
11class KGlobalSettings
12{
13 public:
14 static QFont generalFont();
15 static QFont toolBarFont();
16
17 static QColor toolBarHighlightColor();
18 static QRect desktopGeometry( QWidget * );
19
20 /**
21 * Returns whether KDE runs in single (default) or double click
22 * mode.
23 * see http://developer.kde.org/documentation/standards/kde/style/mouse/index.html
24 * @return true if single click mode, or false if double click mode.
25 **/
26 static bool singleClick();
27
28};
29
30#endif
diff --git a/microkde/kiconloader.cpp b/microkde/kiconloader.cpp
new file mode 100644
index 0000000..4842d71
--- a/dev/null
+++ b/microkde/kiconloader.cpp
@@ -0,0 +1,140 @@
1
2#include "kiconloader.h"
3#include "kglobal.h"
4
5#ifndef DESKTOP_VERSION_OEGEL
6#include <qdir.h>
7QPixmap KIconLoader::loadIcon( const QString& name, KIcon::Group, int,
8 int, QString *, bool ) const
9{
10 QPixmap pix;
11 QString file;
12 file = iconPath() + name+".png";
13 pix.load ( file );
14 // qDebug("KIconLoader::loadIcon %s -----------", file.latin1());
15 return pix;
16}
17QIconSet KIconLoader::loadIconSet( const QString& name) const
18{
19 QPixmap pixmapLoader;
20 QString file;
21 file = iconPath() + name+".png";
22 pixmapLoader.load( file );
23 //qDebug("KIconLoader::loadIconSet: %s ************", file.latin1() );
24 QIconSet is ( pixmapLoader );
25 return is;
26}
27
28QPixmap BarIcon( const QString &name )
29{
30 QPixmap pix;
31 pix.load ( KGlobal::iconLoader()->iconPath() + name +".png" );
32 return pix;
33}
34
35QPixmap DesktopIcon( const QString &name, int )
36{
37 QPixmap pix;
38 pix.load ( KGlobal::iconLoader()->iconPath() + name +".png" );
39 return pix;
40
41}
42
43QPixmap SmallIcon( const QString &name )
44{
45 QPixmap pixmapLoader;
46 QString file;
47 file =KGlobal::iconLoader()->iconPath() + name +".png";
48 pixmapLoader.load( file );
49 return pixmapLoader;
50
51}
52
53QPixmap SmallIconSet( const QString &name )
54{
55 QPixmap pixmapLoader;
56 QString file;
57 file =KGlobal::iconLoader()->iconPath() + name +".png";
58 pixmapLoader.load( file );
59 return pixmapLoader;
60}
61
62
63#else
64
65#include <qpe/resource.h>
66#include <kglobal.h>
67QPixmap KIconLoader::loadIcon( const QString& name, KIcon::Group, int,
68 int, QString *, bool ) const
69{
70 QString px = this->iconPath() + "/" + name;
71
72 QPixmap p = Resource::loadPixmap( px );
73 QPixmap* pPtr = &p;
74 if (pPtr == 0)
75 qDebug("KIconLoader::loadIcon: %s not found", px.latin1());
76
77 return p;
78}
79
80QIconSet KIconLoader::loadIconSet( const QString& name) const
81{
82 QString px = this->iconPath() + "/" + name;
83
84 QIconSet is ;//= Resource::loadIconSet( px );
85 QIconSet* isPtr = 0;//LR&is;
86 if (isPtr == 0)
87 qDebug("KIconLoader::loadIconSet: %s not foun", px.latin1());
88
89 return is;
90}
91
92QPixmap BarIcon( const QString &name )
93{
94 QPixmap p = KGlobal::iconLoader()->loadIcon(name, KIcon::Desktop);
95 return p;
96}
97
98QPixmap DesktopIcon( const QString &name, int )
99{
100 QPixmap p = KGlobal::iconLoader()->loadIcon(name, KIcon::Desktop);
101 return p;
102}
103
104QPixmap SmallIcon( const QString &name )
105{
106 QPixmap p = KGlobal::iconLoader()->loadIcon(name, KIcon::Desktop);
107 return p;
108}
109
110QPixmap SmallIconSet( const QString &name )
111{
112 QPixmap p = KGlobal::iconLoader()->loadIcon(name, KIcon::Desktop);
113 return p;
114}
115
116#endif
117
118//US
119QString KIconLoader::setIconPath( const QString &iconpath)
120{
121 QString _old = mIconpath;
122 mIconpath = iconpath;
123
124 return _old;
125}
126QString KIconLoader::iconPath( const QString & name, int ) const
127{
128 return mIconpath + name + ".png";
129}
130
131QString KIconLoader::iconPath( /*US const QString &, int */) const
132{
133 // LR we set the path at startup
134 // if (KGlobal::getDesktopSize() == KGlobal::Small)
135 //return mIconpath + "/icons16";
136
137 //Fall back to the defaultpath
138 return mIconpath;
139}
140
diff --git a/microkde/kiconloader.h b/microkde/kiconloader.h
new file mode 100644
index 0000000..68fec4e
--- a/dev/null
+++ b/microkde/kiconloader.h
@@ -0,0 +1,52 @@
1#ifndef MINIKDE_KICONLOADER_H
2#define MINIKDE_KICONLOADER_H
3
4#include <qpixmap.h>
5#include <qstring.h>
6//US
7#include <qiconset.h>
8
9class KIcon
10{
11 public:
12 enum Group { NoGroup=-1, Desktop=0, Toolbar, MainToolbar, Small,
13 Panel, LastGroup, User };
14 enum StdSizes { SizeSmall=16, SizeMedium=32, SizeLarge=48 };
15 enum States { DefaultState, ActiveState, DisabledState, LastState };
16};
17
18class KIconLoader
19{
20 public:
21 KIconLoader()
22 : mIconpath(0) {}
23
24 KIconLoader( const QString &iconpath )
25 : mIconpath(iconpath) {}
26
27//US QPixmap loadIcon( const QString &name, int );
28
29 QPixmap loadIcon(const QString& name, KIcon::Group group, int size=0,
30 int state=KIcon::DefaultState, QString *path_store=0,
31 bool canReturnNull=false) const;
32
33//US
34 QString setIconPath( const QString &);
35 QString iconPath( /*US const QString &, int */) const;
36 QString iconPath( const QString &, int ) const;
37 QIconSet loadIconSet( const QString &name) const;
38
39//US to make this class usable for different applications, we have to add a iconpathvariable
40 private:
41 QString mIconpath;
42};
43
44QPixmap BarIcon(const QString& name);
45
46QPixmap DesktopIcon(const QString& name, int);
47
48QPixmap SmallIcon(const QString& name);
49
50QPixmap SmallIconSet( const QString &name );
51
52#endif
diff --git a/microkde/kio/job.h b/microkde/kio/job.h
new file mode 100644
index 0000000..21c56b0
--- a/dev/null
+++ b/microkde/kio/job.h
@@ -0,0 +1,12 @@
1#ifndef MINIKDE_KIO_JOB_H
2#define MINIKDE_KIO_JOB_H
3
4namespace KIO {
5
6class Job
7{
8};
9
10}
11
12#endif
diff --git a/microkde/kio/kfile/kurlrequester.cpp b/microkde/kio/kfile/kurlrequester.cpp
new file mode 100644
index 0000000..6d39308
--- a/dev/null
+++ b/microkde/kio/kfile/kurlrequester.cpp
@@ -0,0 +1,406 @@
1/* This file is part of the KDE libraries
2 Copyright (C) 1999,2000,2001 Carsten Pfeiffer <pfeiffer@kde.org>
3
4 library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License version 2, as published by the Free Software Foundation.
7
8 This library is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 Library General Public License for more details.
12
13 You should have received a copy of the GNU Library General Public License
14 along with this library; see the file COPYING.LIB. If not, write to
15 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16 Boston, MA 02111-1307, USA.
17*/
18
19
20#include <sys/stat.h>
21#ifdef _WIN32_
22
23#else
24#include <unistd.h>
25#endif
26#include <qstring.h>
27//US #include <qtooltip.h>
28
29#include <qpushbutton.h>
30
31//US #include <kaccel.h>
32//US #include <kcombobox.h>
33#include <kdebug.h>
34#include <kdialog.h>
35#include <kfiledialog.h>
36#include <kglobal.h>
37#include <kiconloader.h>
38#include <klineedit.h>
39#include <klocale.h>
40//US #include <kurlcompletion.h>
41//US #include <kurldrag.h>
42//US #include <kprotocolinfo.h>
43
44
45#include "kurlrequester.h"
46
47
48class KURLDragPushButton : public QPushButton
49{
50public:
51 KURLDragPushButton( QWidget *parent, const char *name=0 )
52 : QPushButton( parent, name ) {
53 //US setDragEnabled( true );
54 }
55 ~KURLDragPushButton() {}
56
57 void setURL( const KURL& url ) {
58 m_urls.clear();
59 m_urls.append( url );
60 }
61
62 /* not needed so far
63 void setURLs( const KURL::List& urls ) {
64 m_urls = urls;
65 }
66 const KURL::List& urls() const { return m_urls; }
67 */
68
69protected:
70/*US
71 virtual QDragObject *dragObject() {
72 if ( m_urls.isEmpty() )
73 return 0L;
74
75 QDragObject *drag = KURLDrag::newDrag( m_urls, this, "url drag" );
76 return drag;
77 }
78*/
79private:
80 KURL::List m_urls;
81
82};
83
84
85/*
86*************************************************************************
87*/
88
89class KURLRequester::KURLRequesterPrivate
90{
91public:
92 KURLRequesterPrivate() {
93 edit = 0L;
94 //UScombo = 0L;
95//US fileDialogMode = KFile::File | KFile::ExistingOnly | KFile::LocalOnly;
96 }
97
98 void setText( const QString& text ) {
99/*US
100 if ( combo )
101 {
102 if (combo->editable())
103 {
104 combo->setEditText( text );
105 }
106 else
107 {
108 combo->insertItem( text );
109 combo->setCurrentItem( combo->count()-1 );
110 }
111 }
112 else
113*/
114 {
115 edit->setText( text );
116 }
117 }
118
119 void connectSignals( QObject *receiver ) {
120 QObject *sender;
121 /*USif ( combo )
122 sender = combo;
123 else
124*/
125 sender = edit;
126
127 connect( sender, SIGNAL( textChanged( const QString& )),
128 receiver, SIGNAL( textChanged( const QString& )));
129 connect( sender, SIGNAL( returnPressed() ),
130 receiver, SIGNAL( returnPressed() ));
131 //USconnect( sender, SIGNAL( returnPressed( const QString& ) ),
132 //US receiver, SIGNAL( returnPressed( const QString& ) ));
133 }
134/*US
135 void setCompletionObject( KCompletion *comp ) {
136 if ( combo )
137 combo->setCompletionObject( comp );
138 else
139 edit->setCompletionObject( comp );
140 }
141 */
142 /**
143 * replaces ~user or $FOO, if necessary
144 */
145 QString url() {
146 QString txt = /*US combo ? combo->currentText() : */ edit->text();
147/*US KURLCompletion *comp;
148 if ( combo )
149 comp = dynamic_cast<KURLCompletion*>(combo->completionObject());
150 else
151 comp = dynamic_cast<KURLCompletion*>(edit->completionObject());
152
153 if ( comp )
154 return comp->replacedPath( txt );
155 else
156*/
157 return txt;
158 }
159
160 KLineEdit *edit;
161//US KComboBox *combo;
162 int fileDialogMode;
163 QString fileDialogFilter;
164};
165
166
167/*US
168KURLRequester::KURLRequester( QWidget *editWidget, QWidget *parent,
169 const char *name )
170 : QHBox( parent, name )
171{
172 d = new KURLRequesterPrivate;
173
174 // must have this as parent
175 editWidget->reparent( this, 0, QPoint(0,0) );
176//US d->edit = dynamic_cast<KLineEdit*>( editWidget );
177 d->edit = (KLineEdit*)( editWidget );
178//US d->combo = dynamic_cast<KComboBox*>( editWidget );
179
180 init();
181}
182*/
183
184KURLRequester::KURLRequester( QWidget *parent, const char *name )
185 : QHBox( parent, name )
186{
187 d = new KURLRequesterPrivate;
188 init();
189}
190
191
192KURLRequester::KURLRequester( const QString& url, QWidget *parent,
193 const char *name )
194 : QHBox( parent, name )
195{
196 d = new KURLRequesterPrivate;
197 init();
198 setURL( url );
199}
200
201
202KURLRequester::~KURLRequester()
203{
204//US delete myCompletion;
205 delete myFileDialog;
206 delete d;
207}
208
209
210void KURLRequester::init()
211{
212 myFileDialog = 0L;
213 myShowLocalProt = false;
214
215 if (/*US !d->combo && */ !d->edit )
216 d->edit = new KLineEdit( this, "KURLRequester::KLineEdit" );
217
218 myButton = new KURLDragPushButton( this, "kfile button");
219 QIconSet iconSet = SmallIconSet("fileopen");
220 QPixmap pixMap = iconSet.pixmap( QIconSet::Small, QIconSet::Normal );
221 myButton->setIconSet( iconSet );
222 myButton->setFixedSize( pixMap.width()+8, pixMap.height()+8 );
223//US QToolTip::add(myButton, i18n("Open file dialog"));
224
225 connect( myButton, SIGNAL( pressed() ), SLOT( slotUpdateURL() ));
226
227 setSpacing( KDialog::spacingHint() );
228
229 QWidget *widget = /*US d->combo ? (QWidget*) d->combo : */ (QWidget*) d->edit;
230 setFocusProxy( widget );
231
232 d->connectSignals( this );
233 connect( myButton, SIGNAL( clicked() ), this, SLOT( slotOpenDialog() ));
234/*US
235 myCompletion = new KURLCompletion();
236 d->setCompletionObject( myCompletion );
237
238 KAccel *accel = new KAccel( this );
239 accel->insert( KStdAccel::Open, this, SLOT( slotOpenDialog() ));
240 accel->readSettings();
241*/
242}
243
244
245void KURLRequester::setURL( const QString& url )
246{
247 bool hasLocalPrefix = (url.startsWith("file:"));
248
249 if ( !myShowLocalProt && hasLocalPrefix )
250 d->setText( url.mid( 5, url.length()-5 ));
251 else
252 d->setText( url );
253}
254
255void KURLRequester::setCaption( const QString& caption )
256{
257 //USfileDialog()->setCaption( caption );
258 //USQWidget::setCaption( caption );
259}
260
261QString KURLRequester::url() const
262{
263 return d->url();
264}
265
266
267void KURLRequester::slotOpenDialog()
268{
269 emit openFileDialog( this );
270
271//US use our special KFIleDialog instead
272 KURL u( url() );
273 //QString fn = u.url();
274 QString fn = d->edit->text();
275 fn = KFileDialog::getSaveFileName( fn, "Save backup filename", this );
276
277 if ( fn == "" )
278 return;
279
280 setURL( fn );
281 emit urlSelected( d->url() );
282/*US
283 KFileDialog *dlg = fileDialog();
284 if ( !d->url().isEmpty() ) {
285 KURL u( url() );
286 // If we won't be able to list it (e.g. http), then don't try :)
287 if ( KProtocolInfo::supportsListing( u.protocol() ) )
288 dlg->setSelection( u.url() );
289 }
290
291 if ( dlg->exec() == QDialog::Accepted )
292 {
293 setURL( dlg->selectedURL().prettyURL() );
294 emit urlSelected( d->url() );
295 }
296*/
297
298}
299
300void KURLRequester::setMode(unsigned int mode)
301{
302/*US
303 Q_ASSERT( (mode & KFile::Files) == 0 );
304 d->fileDialogMode = mode;
305 if ( (mode & KFile::Directory) && !(mode & KFile::File) )
306 myCompletion->setMode( KURLCompletion::DirCompletion );
307
308 if (myFileDialog)
309 myFileDialog->setMode( d->fileDialogMode );
310*/
311}
312
313void KURLRequester::setFilter(const QString &filter)
314{
315/*US
316 d->fileDialogFilter = filter;
317 if (myFileDialog)
318 myFileDialog->setFilter( d->fileDialogFilter );
319*/
320}
321
322KFileDialog * KURLRequester::fileDialog() const
323{
324/*US
325 if ( !myFileDialog ) {
326 QWidget *p = parentWidget();
327 myFileDialog = new KFileDialog( QString::null, QString::null, p,
328 "file dialog", true );
329
330 myFileDialog->setMode( d->fileDialogMode );
331 myFileDialog->setFilter( d->fileDialogFilter );
332 }
333
334 return myFileDialog;
335*/
336 return 0;
337}
338
339
340void KURLRequester::setShowLocalProtocol( bool b )
341{
342 if ( myShowLocalProt == b )
343 return;
344
345 myShowLocalProt = b;
346 setURL( url() );
347}
348
349void KURLRequester::clear()
350{
351 d->setText( QString::null );
352}
353
354KLineEdit * KURLRequester::lineEdit() const
355{
356 return d->edit;
357}
358/*US
359KComboBox * KURLRequester::comboBox() const
360{
361 return d->combo;
362}
363*/
364void KURLRequester::slotUpdateURL()
365{
366 // bin compat, myButton is declared as QPushButton
367//US KURL u( QDir::currentDirPath() + '/', url() );
368 KURL u( url() );
369 (static_cast<KURLDragPushButton *>( myButton))->setURL( u );
370}
371
372QPushButton * KURLRequester::button() const
373{
374 return myButton;
375}
376/*US
377KEditListBox::CustomEditor KURLRequester::customEditor()
378{
379 setSizePolicy(QSizePolicy( QSizePolicy::Preferred,
380 QSizePolicy::Fixed));
381
382 KLineEdit *edit = d->edit;
383 if ( !edit && d->combo )
384 edit = dynamic_cast<KLineEdit*>( d->combo->lineEdit() );
385
386#ifndef NDEBUG
387 if ( !edit )
388 kdWarning() << "KURLRequester's lineedit is not a KLineEdit!??\n";
389#endif
390
391 KEditListBox::CustomEditor editor( this, edit );
392 return editor;
393}
394*/
395void KURLRequester::virtual_hook( int, void* )
396{ /*BASE::virtual_hook( id, data );*/ }
397
398/*US
399KURLComboRequester::KURLComboRequester( QWidget *parent,
400 const char *name )
401 : KURLRequester( new KComboBox(false), parent, name)
402{
403}
404*/
405
406//US #include "kurlrequester.moc"
diff --git a/microkde/kio/kfile/kurlrequester.h b/microkde/kio/kfile/kurlrequester.h
new file mode 100644
index 0000000..3253dd5
--- a/dev/null
+++ b/microkde/kio/kfile/kurlrequester.h
@@ -0,0 +1,269 @@
1/* This file is part of the KDE libraries
2 Copyright (C) 1999,2000,2001 Carsten Pfeiffer <pfeiffer@kde.org>
3
4 library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License version 2, as published by the Free Software Foundation.
7
8 This library is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 Library General Public License for more details.
12
13 You should have received a copy of the GNU Library General Public License
14 along with this library; see the file COPYING.LIB. If not, write to
15 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16 Boston, MA 02111-1307, USA.
17*/
18
19
20#ifndef KURLREQUESTER_H
21#define KURLREQUESTER_H
22
23#include <qhbox.h>
24
25#include <keditlistbox.h>
26//US #include <kfile.h>
27//US #include <kpushbutton.h>
28#include <kurl.h>
29
30//US class KComboBox;
31
32class KFileDialog;
33class KLineEdit;
34//US class KURLCompletion;
35class KURLDragPushButton;
36
37class QPushButton;
38class QString;
39class QTimer;
40
41/**
42 * This class is a widget showing a lineedit and a button, which invokes a
43 * filedialog. File name completion is available in the lineedit.
44 *
45 * The defaults for the filedialog are to ask for one existing local file, i.e.
46 * KFileDialog::setMode( KFile::File | KFile::ExistingOnly | KFile::LocalOnly )
47 * The default filter is "*", i.e. show all files, and the start directory is
48 * the current working directory, or the last directory where a file has been
49 * selected.
50 *
51 * You can change this behavior by using @ref setMode() or @ref setFilter().
52 *
53 * @short A widget to request a filename/url from the user
54 * @author Carsten Pfeiffer <pfeiffer@kde.org>
55 */
56class KURLRequester : public QHBox
57{
58 Q_OBJECT
59 Q_PROPERTY( QString url READ url WRITE setURL )
60
61public:
62 /**
63 * Constructs a KURLRequester widget.
64 */
65 KURLRequester( QWidget *parent=0, const char *name=0 );
66
67 /**
68 * Constructs a KURLRequester widget with the initial URL @p url.
69 */
70 KURLRequester( const QString& url, QWidget *parent=0, const char *name=0 );
71
72 /**
73 * Special constructor, which creates a KURLRequester widget with a custom
74 * edit-widget. The edit-widget can be either a KComboBox or a KLineEdit
75 * (or inherited thereof). Note: for geometry management reasons, the
76 * edit-widget is reparented to have the KURLRequester as parent.
77 * @param modal specifies whether the filedialog should be opened as modal
78 * or not.
79 */
80//US KURLRequester( QWidget *editWidget, QWidget *parent, const char *name=0 );
81 /**
82 * Destructs the KURLRequester.
83 */
84 ~KURLRequester();
85
86 /**
87 * @returns the current url in the lineedit. May be malformed, if the user
88 * entered something weird. ~user or environment variables are substituted
89 * for local files.
90 */
91 QString url() const;
92
93 /**
94 * Enables/disables showing file:/ in the lineedit, when a local file has
95 * been selected in the filedialog or was set via @ref setURL().
96 * Default is false, not showing file:/
97 * @see #showLocalProtocol
98 */
99 void setShowLocalProtocol( bool b );
100
101 /**
102 * Sets the mode of the file dialog.
103 * Note: you can only select one file with the filedialog,
104 * so KFile::Files doesn't make much sense.
105 * @see KFileDialog::setMode()
106 */
107 void setMode( unsigned int m );
108
109 /**
110 * Sets the filter for the file dialog.
111 * @see KFileDialog::setFilter()
112 */
113 void setFilter( const QString& filter );
114
115 /**
116 * @returns whether local files will be prefixed with file:/ in the
117 * lineedit
118 * @see #setShowLocalProtocol
119 */
120 bool showLocalProtocol() const { return myShowLocalProt; }
121
122 /**
123 * @returns a pointer to the filedialog
124 * You can use this to customize the dialog, e.g. to specify a filter.
125 * Never returns 0L.
126 */
127 virtual KFileDialog * fileDialog() const;
128
129 /**
130 * @returns a pointer to the lineedit, either the default one, or the
131 * special one, if you used the special constructor.
132 *
133 * It is provided so that you can e.g. set an own completion object
134 * (e.g. @ref KShellCompletion) into it.
135 */
136 KLineEdit * lineEdit() const;
137
138 /**
139 * @returns a pointer to the combobox, in case you have set one using the
140 * special constructor. Returns 0L otherwise.
141 */
142//US KComboBox * comboBox() const;
143
144 /**
145 * @returns a pointer to the pushbutton. It is provided so that you can
146 * specify an own pixmap or a text, if you really need to.
147 */
148 QPushButton * button() const;
149
150 /**
151 * @returns the KURLCompletion object used in the lineedit/combobox.
152 */
153//US KURLCompletion *completionObject() const { return myCompletion; }
154
155 /**
156 * @returns an object, suitable for use with KEditListBox. It allows you
157 * to put this KURLRequester into a KEditListBox.
158 * Basically, do it like this:
159 * <pre>
160 * KURLRequester *req = new KURLRequester( someWidget );
161 * [...]
162 * KEditListBox *editListBox = new KEditListBox( i18n("Some Title"), req->customEditor(), someWidget );
163 * </pre>
164 * @since 3.1
165 */
166//US KEditListBox::CustomEditor customEditor();
167
168public slots:
169 /**
170 * Sets the url in the lineedit to @p url. Depending on the state of
171 * @ref showLocalProtocol(), file:/ on local files will be shown or not.
172 * @since 3.1
173 */
174 void setURL( const QString& url );
175
176 /**
177 * @reimp
178 * Sets the caption of the file dialog.
179 * @since 3.1
180 */
181 virtual void setCaption( const QString& caption );
182
183 /**
184 * Clears the lineedit/combobox.
185 */
186 void clear();
187
188signals:
189 // forwards from LineEdit
190 /**
191 * Emitted when the text in the lineedit changes.
192 * The parameter contains the contents of the lineedit.
193 * @since 3.1
194 */
195 void textChanged( const QString& );
196
197 /**
198 * Emitted when return or enter was pressed in the lineedit.
199 */
200 void returnPressed();
201
202 /**
203 * Emitted when return or enter was pressed in the lineedit.
204 * The parameter contains the contents of the lineedit.
205 */
206 void returnPressed( const QString& );
207
208 /**
209 * Emitted before the filedialog is going to open. Connect
210 * to this signal to "configure" the filedialog, e.g. set the
211 * filefilter, the mode, a preview-widget, etc. It's usually
212 * not necessary to set a URL for the filedialog, as it will
213 * get set properly from the editfield contents.
214 *
215 * If you use multiple KURLRequesters, you can connect all of them
216 * to the same slot and use the given KURLRequester pointer to know
217 * which one is going to open.
218 */
219 void openFileDialog( KURLRequester * );
220
221 /**
222 * Emitted when the user changed the URL via the file dialog.
223 * The parameter contains the contents of the lineedit.
224 */
225 void urlSelected( const QString& );
226
227protected:
228 void init();
229
230//US KURLCompletion * myCompletion;
231
232
233private:
234 KURLDragPushButton * myButton;
235 bool myShowLocalProt;
236 mutable KFileDialog * myFileDialog;
237
238
239protected slots:
240 /**
241 * Called when the button is pressed to open the filedialog.
242 * Also called when @ref KStdAccel::Open (default is Ctrl-O) is pressed.
243 */
244 void slotOpenDialog();
245
246private slots:
247 void slotUpdateURL();
248
249protected:
250 virtual void virtual_hook( int id, void* data );
251private:
252 class KURLRequesterPrivate;
253 KURLRequesterPrivate *d;
254};
255/*US
256class KURLComboRequester : public KURLRequester // For use in Qt Designer
257{
258 Q_OBJECT
259public:
260*/
261 /**
262 * Constructs a KURLRequester widget with a combobox.
263 */
264/*US
265 KURLComboRequester( QWidget *parent=0, const char *name=0 );
266};
267*/
268
269#endif // KURLREQUESTER_H
diff --git a/microkde/klineedit.h b/microkde/klineedit.h
new file mode 100644
index 0000000..65e2f59
--- a/dev/null
+++ b/microkde/klineedit.h
@@ -0,0 +1,24 @@
1#ifndef MINIKDE_KLINEEDIT_H
2#define MINIKDE_KLINEEDIT_H
3
4#include <qlineedit.h>
5
6#ifndef DESKTOP_VERSION
7#include <qpe/qpeapplication.h>
8#endif
9
10
11class KLineEdit : public QLineEdit
12{
13 public:
14 KLineEdit( QWidget *parent=0, const char *name=0 ) :
15 QLineEdit( parent, name ) {
16#ifndef DESKTOP_VERSION
17 QPEApplication::setStylusOperation( this, QPEApplication::RightOnHold );
18#endif
19}
20
21 void setTrapReturnKey( bool ) {}
22};
23
24#endif
diff --git a/microkde/klineeditdlg.h b/microkde/klineeditdlg.h
new file mode 100644
index 0000000..68e9252
--- a/dev/null
+++ b/microkde/klineeditdlg.h
@@ -0,0 +1,34 @@
1#ifndef MICROKDE_KLINEEDITDLG_H
2#define MICROKDE_KLINEEDITDLG_H
3
4#include "kdialogbase.h"
5#include <klineedit.h>
6#include <qlayout.h>
7#include <qlabel.h>
8#include <qdialog.h>
9#include <qpushbutton.h>
10
11class KLineEditDlg : public QDialog
12{
13 public:
14 KLineEditDlg( const QString & text, const QString & editText, QWidget *parent ) :
15 QDialog( parent,"lineedit", true ) {
16 QLabel* lab = new QLabel( text, this );
17 mEdit = new KLineEdit( this );
18 QVBoxLayout* vl = new QVBoxLayout( this );
19 vl->setSpacing(5);
20 vl->setMargin(7);
21 vl->addWidget( lab );
22 vl->addWidget( mEdit );
23 mEdit->setText( editText );
24 QPushButton * p = new QPushButton (" OK ", this );
25 vl->addWidget( p );
26 connect( p, SIGNAL ( clicked () ), this , SLOT (accept() ) );
27 }
28
29 QString text() { return mEdit->text(); }
30 private:
31 KLineEdit* mEdit;
32};
33
34#endif
diff --git a/microkde/kmessagebox.cpp b/microkde/kmessagebox.cpp
new file mode 100644
index 0000000..f06708a
--- a/dev/null
+++ b/microkde/kmessagebox.cpp
@@ -0,0 +1,90 @@
1#include "kmessagebox.h"
2#include "klocale.h"
3
4#include <qmessagebox.h>
5
6void KMessageBox::sorry( QWidget *parent,
7 const QString &text,
8 const QString &caption, bool )
9{
10 QString cap = caption;
11
12 if (cap.isEmpty()) {
13 cap = i18n("Sorry");
14 }
15
16 QMessageBox::warning( parent, cap, text );
17}
18
19int KMessageBox::warningContinueCancel( QWidget *parent,
20 const QString &text,
21 const QString &caption,
22 const QString &buttonContinue,
23 const QString &dontAskAgainName,
24 bool notify )
25{
26 QString cap = caption;
27
28 int result = QMessageBox::warning( parent, cap, text, buttonContinue,
29 dontAskAgainName);
30
31 if ( result == 0 ) return KMessageBox::Continue;
32 return KMessageBox::Cancel;
33}
34
35int KMessageBox::warningYesNoCancel( QWidget *parent,
36 const QString &text,
37 const QString &caption,
38 const QString &buttonYes,
39 const QString &buttonNo )
40{
41 QString cap = caption;
42
43 int result = QMessageBox::warning( parent, cap, text,buttonYes ,buttonNo,
44 i18n("Cancel") );
45
46 if ( result == 0 ) return KMessageBox::Yes;
47 else if ( result == 1 ) return KMessageBox::No;
48 return KMessageBox::Cancel;
49}
50
51int KMessageBox::questionYesNo(QWidget *parent,
52 const QString &text,
53 const QString &caption)
54{
55 QString cap = caption;
56
57 int result = QMessageBox::warning( parent, cap, text, i18n("Yes"),
58 i18n("No") );
59
60 if ( result == 0 ) return KMessageBox::Yes;
61 else return KMessageBox::No;
62}
63
64void KMessageBox::error( QWidget *parent,
65 const QString &text,
66 const QString &caption, bool notify )
67{
68 QString cap = caption;
69
70 if (cap.isEmpty()) {
71 cap = i18n("Error");
72 }
73
74 QMessageBox::critical( parent, cap, text );
75}
76
77void KMessageBox::information( QWidget *parent,
78 const QString &text,
79 const QString &caption,
80 const QString &,
81 bool )
82{
83 QString cap = caption;
84
85 if (cap.isEmpty()) {
86 cap = i18n("Information");
87 }
88
89 QMessageBox::information( parent, cap, text );
90}
diff --git a/microkde/kmessagebox.h b/microkde/kmessagebox.h
new file mode 100644
index 0000000..01d83b1
--- a/dev/null
+++ b/microkde/kmessagebox.h
@@ -0,0 +1,47 @@
1#ifndef MINIKDE_KMESSAGEBOX_H
2#define MINIKDE_KMESSAGEBOX_H
3
4#include <qstring.h>
5
6#include "klocale.h"
7class QWidget;
8
9class KMessageBox
10{
11 public:
12 enum { Ok = 1, Cancel = 2, Yes = 3, No = 4, Continue = 5 };
13
14 static void sorry(QWidget *parent,
15 const QString &text,
16 const QString &caption = QString::null, bool notify=true);
17
18 static int warningContinueCancel(QWidget *parent,
19 const QString &text,
20 const QString &caption = i18n("Warning"),
21 const QString &buttonContinue =i18n("Continue"),
22 const QString &dontAskAgainName = i18n("Cancel"),
23 bool notify=true );
24
25 static int warningYesNoCancel(QWidget *parent,
26 const QString &text,
27 const QString &caption = i18n("Warning"),
28 const QString &buttonYes = i18n("Yes"),
29 const QString &buttonNo = i18n("No"));
30
31 static int questionYesNo(QWidget *parent,
32 const QString &text,
33 const QString &caption = i18n("Question"));
34
35 static void error(QWidget *parent,
36 const QString &text,
37 const QString &caption = i18n("Error"), bool notify=true);
38
39 static void information(QWidget *parent,
40 const QString &text,
41 const QString &caption = i18n("Information"),
42 const QString &dontShowAgainName = QString::null,
43 bool notify=true);
44};
45
46
47#endif
diff --git a/microkde/knotifyclient.h b/microkde/knotifyclient.h
new file mode 100644
index 0000000..118026a
--- a/dev/null
+++ b/microkde/knotifyclient.h
@@ -0,0 +1,14 @@
1#ifndef MINIKDE_KNOTIFYCLIENT_H
2#define MINIKDE_KNOTIFYCLIENT_H
3
4#include <qstring.h>
5
6class KNotifyClient
7{
8 public:
9
10 static void beep() {}
11 static void beep( const QString & ) {}
12};
13
14#endif
diff --git a/microkde/kprinter.h b/microkde/kprinter.h
new file mode 100644
index 0000000..b99d689
--- a/dev/null
+++ b/microkde/kprinter.h
@@ -0,0 +1,8 @@
1#ifndef MINIKDE_KPRINTER_H
2#define MINIKDE_KPRINTER_H
3
4#include <qprinter.h>
5
6#define KPrinter QPrinter
7
8#endif
diff --git a/microkde/kprocess.cpp b/microkde/kprocess.cpp
new file mode 100644
index 0000000..665d0bd
--- a/dev/null
+++ b/microkde/kprocess.cpp
@@ -0,0 +1,19 @@
1#include "kprocess.h"
2
3void KProcess::clearArguments()
4{
5// mProcess.clearArguments();
6}
7
8KProcess & KProcess::operator<<( const QString &arg )
9{
10// mProcess.addArgument( arg );
11
12 return *this;
13}
14
15bool KProcess::start( KProcess::RunMode )
16{
17// return mProcess.start();
18 return false;
19}
diff --git a/microkde/kprocess.h b/microkde/kprocess.h
new file mode 100644
index 0000000..dffe96d
--- a/dev/null
+++ b/microkde/kprocess.h
@@ -0,0 +1,22 @@
1#ifndef MINIKDE_KPROCESS_H
2#define MINIKDE_KPROCESS_H
3
4#include <qobject.h>
5//#include <qpe/qprocess.h>
6
7class KProcess : public QObject
8{
9 public:
10 enum RunMode { DontCare, NotifyOnExit, Block };
11
12 void clearArguments();
13
14 KProcess & operator<<( const QString & );
15
16 bool start( RunMode mode = DontCare );
17
18 private:
19// QProcess mProcess;
20};
21
22#endif
diff --git a/microkde/kresources/configdialog.cpp b/microkde/kresources/configdialog.cpp
new file mode 100644
index 0000000..48d9137
--- a/dev/null
+++ b/microkde/kresources/configdialog.cpp
@@ -0,0 +1,137 @@
1/*
2 This file is part of libkresources.
3
4 Copyright (c) 2002 Tobias Koenig <tokoe@kde.org>
5 Copyright (c) 2002 Jan-Pascal van Best <janpascal@vanbest.org>
6 Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org>
7
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Library General Public
10 License as published by the Free Software Foundation; either
11 version 2 of the License, or (at your option) any later version.
12
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Library General Public License for more details.
17
18 You should have received a copy of the GNU Library General Public License
19 along with this library; see the file COPYING.LIB. If not, write to
20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA.
22*/
23
24#include <klocale.h>
25#include <kglobal.h>
26#include <kmessagebox.h>
27
28#include <qgroupbox.h>
29#include <qlabel.h>
30#include <qlayout.h>
31#include <qpushbutton.h>
32
33#include <qcheckbox.h>
34
35#include <kbuttonbox.h>
36#include <kdialog.h>
37#include <klineedit.h>
38
39#include "factory.h"
40#include "configwidget.h"
41#include "configdialog.h"
42
43using namespace KRES;
44
45ConfigDialog::ConfigDialog( QWidget *parent, const QString& resourceFamily,
46 /*const QString& type,*/ Resource* resource, /*KConfig *config, */const char *name )
47 : KDialogBase( parent, name, true, i18n( "Resource Configuration" ),
48 Ok|Cancel, Ok, true )/*, mConfig( config )*/, mResource( resource )
49{
50 Factory *factory = Factory::self( resourceFamily );
51
52//US resize( 250, 240 );
53 resize( KMIN(KGlobal::getDesktopWidth(), 250), KMIN(KGlobal::getDesktopHeight(), 240));
54
55//US QFrame *main = makeMainWidget();
56 QFrame *main = plainPage();
57
58 QVBoxLayout *mainLayout = new QVBoxLayout( main, 0, spacingHint() );
59
60 QGroupBox *generalGroupBox = new QGroupBox( 2, Qt::Horizontal, main );
61 generalGroupBox->layout()->setSpacing( spacingHint() );
62 generalGroupBox->setTitle( i18n( "General Settings" ) );
63
64 new QLabel( i18n( "Name:" ), generalGroupBox );
65
66 mName = new KLineEdit( generalGroupBox );
67
68 mReadOnly = new QCheckBox( i18n( "Read-only" ), generalGroupBox );
69
70 mName->setText( mResource->resourceName() );
71 mReadOnly->setChecked( mResource->readOnly() );
72
73 mainLayout->addWidget( generalGroupBox );
74
75 QGroupBox *resourceGroupBox = new QGroupBox( 2, Qt::Horizontal, main );
76 resourceGroupBox->layout()->setSpacing( spacingHint());
77 resourceGroupBox->setTitle( i18n( "%1 Resource Settings" )
78 .arg( factory->typeName( resource->type() ) ) );
79 mainLayout->addWidget( resourceGroupBox );
80
81 mainLayout->addStretch();
82
83 mConfigWidget = factory->configWidget( resource->type(), resourceGroupBox );
84 if ( mConfigWidget ) {
85 mConfigWidget->setInEditMode( false );
86 mConfigWidget->loadSettings( mResource );
87 mConfigWidget->show();
88 connect( mConfigWidget, SIGNAL( setReadOnly( bool ) ),
89 SLOT( setReadOnly( bool ) ) );
90 }
91
92 connect( mName, SIGNAL( textChanged(const QString &)),
93 SLOT( slotNameChanged(const QString &)));
94
95 slotNameChanged( mName->text() );
96
97//US setMinimumSize( 400, 250 );
98 setMinimumSize( KMIN(KGlobal::getDesktopWidth(), 400), KMIN(KGlobal::getDesktopHeight(), 250));
99
100}
101
102void ConfigDialog::setInEditMode( bool value )
103{
104 if ( mConfigWidget )
105 mConfigWidget->setInEditMode( value );
106}
107
108void ConfigDialog::slotNameChanged( const QString &text)
109{
110 enableButtonOK( !text.isEmpty() );
111}
112
113void ConfigDialog::setReadOnly( bool value )
114{
115 mReadOnly->setChecked( value );
116}
117
118void ConfigDialog::accept()
119{
120 if ( mName->text().isEmpty() ) {
121 KMessageBox::sorry( this, i18n( "Please enter a resource name" ) );
122 return;
123 }
124
125 mResource->setResourceName( mName->text() );
126 mResource->setReadOnly( mReadOnly->isChecked() );
127
128 if ( mConfigWidget ) {
129 // First save generic information
130 // Also save setting of specific resource type
131 mConfigWidget->saveSettings( mResource );
132 }
133
134 KDialog::accept();
135}
136
137//US #include "configdialog.moc"
diff --git a/microkde/kresources/configdialog.h b/microkde/kresources/configdialog.h
new file mode 100644
index 0000000..6acc5d9
--- a/dev/null
+++ b/microkde/kresources/configdialog.h
@@ -0,0 +1,60 @@
1/*
2 This file is part of libkresources.
3 Copyright (c) 2002 Tobias Koenig <tokoe@kde.org>
4 Copyright (c) 2002 Jan-Pascal van Best <janpascal@vanbest.org>
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
15
16 You should have received a copy of the GNU Library General Public License
17 along with this library; see the file COPYING.LIB. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.
20*/
21
22#ifndef KRESOURCES_CONFIGDIALOG_H
23#define KRESOURCES_CONFIGDIALOG_H
24
25#include <kdialogbase.h>
26
27class KLineEdit;
28class QCheckBox;
29class KButtonBox;
30
31namespace KRES {
32 class Resource;
33 class ConfigWidget;
34
35class ConfigDialog : public KDialogBase
36{
37 Q_OBJECT
38 public:
39 // Resource=0: create new resource
40 ConfigDialog( QWidget *parent, const QString& resourceFamily,
41 Resource* resource, const char *name = 0);
42
43 void setInEditMode( bool value );
44
45 protected slots:
46 void accept();
47 void setReadOnly( bool value );
48 void slotNameChanged( const QString &text);
49
50 private:
51 ConfigWidget *mConfigWidget;
52 Resource* mResource;
53
54 KLineEdit *mName;
55 QCheckBox *mReadOnly;
56};
57
58}
59
60#endif
diff --git a/microkde/kresources/configpage.cpp b/microkde/kresources/configpage.cpp
new file mode 100644
index 0000000..0f1469d
--- a/dev/null
+++ b/microkde/kresources/configpage.cpp
@@ -0,0 +1,507 @@
1/*
2 This file is part of libkresources.
3
4 Copyright (c) 2002 Tobias Koenig <tokoe@kde.org>
5 Copyright (c) 2002 Jan-Pascal van Best <janpascal@vanbest.org>
6 Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org>
7
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Library General Public
10 License as published by the Free Software Foundation; either
11 version 2 of the License, or (at your option) any later version.
12
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Library General Public License for more details.
17
18 You should have received a copy of the GNU Library General Public License
19 along with this library; see the file COPYING.LIB. If not, write to
20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA.
22*/
23
24#include <qgroupbox.h>
25#include <qinputdialog.h>
26#include <qlabel.h>
27#include <qlayout.h>
28
29#include <kapplication.h>
30#include <kcombobox.h>
31#include <kdebug.h>
32#include <klocale.h>
33#include <kmessagebox.h>
34#include <ksimpleconfig.h>
35#include <kstandarddirs.h>
36#include <kurlrequester.h>
37#include <klistview.h>
38#include <kbuttonbox.h>
39//US #include <ktrader.h>
40
41#include "resource.h"
42#include "configdialog.h"
43
44#include "configpage.h"
45
46//US
47#include <qpushbutton.h>
48#include <qfile.h>
49#include <kglobal.h>
50
51using namespace KRES;
52
53class ConfigViewItem : public QCheckListItem
54{
55 public:
56 ConfigViewItem( QListView *parent, Resource* resource ) :
57 QCheckListItem( parent, resource->resourceName(), CheckBox ),
58 mResource( resource ),
59 mIsStandard( false )
60 {
61 setText( 1, mResource->type() );
62 setOn( mResource->isActive() );
63 }
64
65 void setStandard( bool value )
66 {
67 setText( 2, ( value ? i18n( "Yes" ) : QString::null ) );
68 mIsStandard = value;
69 }
70
71 bool standard() const { return mIsStandard; }
72 bool readOnly() const { return mResource->readOnly(); }
73
74 Resource *resource() { return mResource; }
75
76 private:
77 Resource* mResource;
78
79 bool mIsStandard;
80};
81
82ConfigPage::ConfigPage( QWidget *parent, const char *name )
83 : QWidget( parent, name ),
84 mCurrentManager( 0 ),
85 mCurrentConfig( 0 )
86{
87 setCaption( i18n( "Resource Configuration" ) );
88
89 QVBoxLayout *mainLayout = new QVBoxLayout( this );
90
91 QGroupBox *groupBox = new QGroupBox( i18n( "Resources" ), this );
92 groupBox->setColumnLayout(0, Qt::Vertical );
93 groupBox->layout()->setSpacing( 6 );
94 groupBox->layout()->setMargin( 11 );
95 QGridLayout *groupBoxLayout = new QGridLayout( groupBox->layout(), 2, 2 );
96
97//US mFamilyCombo = new KComboBox( false, groupBox );
98 mFamilyCombo = new KComboBox( groupBox );
99 groupBoxLayout->addMultiCellWidget( mFamilyCombo, 0, 0, 0, 1 );
100
101 mListView = new KListView( groupBox );
102 mListView->setAllColumnsShowFocus( true );
103 mListView->addColumn( i18n( "Name" ) );
104 mListView->addColumn( i18n( "Type" ) );
105 mListView->addColumn( i18n( "Standard" ) );
106
107 groupBoxLayout->addWidget( mListView, 1, 0 );
108
109 KButtonBox *buttonBox = new KButtonBox( groupBox, Vertical );
110 mAddButton = buttonBox->addButton( i18n( "&Add..." ), this, SLOT(slotAdd()) );
111 mRemoveButton = buttonBox->addButton( i18n( "&Remove" ), this, SLOT(slotRemove()) );
112 mRemoveButton->setEnabled( false );
113 mEditButton = buttonBox->addButton( i18n( "&Edit..." ), this, SLOT(slotEdit()) );
114 mEditButton->setEnabled( false );
115 mStandardButton = buttonBox->addButton( i18n( "&Use as Standard" ), this, SLOT(slotStandard()) );
116 mStandardButton->setEnabled( false );
117 buttonBox->layout();
118
119 groupBoxLayout->addWidget( buttonBox, 1, 1 );
120
121 mainLayout->addWidget( groupBox );
122
123 connect( mFamilyCombo, SIGNAL( activated( int ) ),
124 SLOT( slotFamilyChanged( int ) ) );
125 connect( mListView, SIGNAL( selectionChanged() ),
126 SLOT( slotSelectionChanged() ) );
127 connect( mListView, SIGNAL( clicked( QListViewItem * ) ),
128 SLOT( slotItemClicked( QListViewItem * ) ) );
129
130 mLastItem = 0;
131
132//US mConfig = new KConfig( "kcmkresourcesrc" );
133 mConfig = new KConfig( locateLocal( "config", "kcmkresourcesrc") );
134 mConfig->setGroup( "General" );
135
136 load();
137}
138
139ConfigPage::~ConfigPage()
140{
141 QValueList<ResourcePageInfo>::Iterator it;
142 for ( it = mInfoMap.begin(); it != mInfoMap.end(); ++it ) {
143 (*it).mManager->removeListener( this );
144 delete (*it).mManager;
145 delete (*it).mConfig;
146 }
147
148 mConfig->writeEntry( "CurrentFamily", mFamilyCombo->currentItem() );
149 delete mConfig;
150 mConfig = 0;
151}
152
153void ConfigPage::load()
154{
155 kdDebug(5650) << "ConfigPage::load()" << endl;
156
157 mListView->clear();
158
159//US we remove the dynamic pluginloader, and set the one family we need (contact) manually.
160
161//US KTrader::OfferList plugins = KTrader::self()->query( "KResources/Plugin" );
162//US KTrader::OfferList::ConstIterator it;
163//US for ( it = plugins.begin(); it != plugins.end(); ++it ) {
164//US QVariant tmp = (*it)->property( "X-KDE-ResourceFamily" );
165//US QString family = tmp.toString();
166
167 QString family = "contact";
168 if ( !family.isEmpty() ) {
169 if ( !mFamilyMap.contains( family ) ) {
170 mCurrentManager = new Manager<Resource>( family );
171 if ( mCurrentManager ) {
172 mFamilyMap.append( family );
173 mCurrentManager->addListener( this );
174
175 ResourcePageInfo info;
176 info.mManager = mCurrentManager;
177 QString configDir = KGlobal::dirs()->saveLocation( "config" );
178 //QString configDir = KStandardDirs::appDir() + "/config";
179 if ( family == "contact" && QFile::exists( configDir + "/kabcrc" ) ) {
180 info.mConfig = new KConfig( locateLocal( "config", "kabcrc" ) );
181 } else if ( family == "calendar" && QFile::exists( configDir + "/kcalrc" ) ) {
182 info.mConfig = new KConfig( locateLocal( "config", "kcalrc" ) );
183 } else {
184 QString configFile = locateLocal( "config", QString( "kresources/%1/stdrc" ).arg( family ) );
185 info.mConfig = new KConfig( configFile );
186 }
187 info.mManager->readConfig( info.mConfig );
188
189 mInfoMap.append( info );
190 }
191 }
192 }
193//US }
194 mCurrentManager = 0;
195
196 mFamilyCombo->insertStringList( mFamilyMap );
197
198 int currentFamily = mConfig->readNumEntry( "CurrentFamily", 0 );
199 mFamilyCombo->setCurrentItem( currentFamily );
200 slotFamilyChanged( currentFamily );
201}
202
203void ConfigPage::save()
204{
205 saveResourceSettings();
206
207 QValueList<ResourcePageInfo>::Iterator it;
208 for ( it = mInfoMap.begin(); it != mInfoMap.end(); ++it )
209 (*it).mManager->writeConfig( (*it).mConfig );
210
211 emit changed( false );
212}
213
214void ConfigPage::defaults()
215{
216}
217
218void ConfigPage::slotFamilyChanged( int pos )
219{
220 if ( pos < 0 || pos >= (int)mFamilyMap.count() )
221 return;
222
223 saveResourceSettings();
224
225 mFamily = mFamilyMap[ pos ];
226
227//US qDebug("ConfigPage::slotFamilyChanged 4 family=%s", mFamily.latin1());
228
229 mCurrentManager = mInfoMap[ pos ].mManager;
230 mCurrentConfig = mInfoMap[ pos ].mConfig;
231
232 if ( !mCurrentManager )
233 kdDebug(5650) << "ERROR: cannot create ResourceManager<Resource>( mFamily )" << endl;
234
235 mListView->clear();
236
237 if ( mCurrentManager->isEmpty() ) {
238//US qDebug("ConfigPage::slotFamilyChanged 4.1 mCurrentManager=%ul", mCurrentManager );
239
240 defaults();
241 }
242
243 Resource *standardResource = mCurrentManager->standardResource();
244
245//US qDebug("ConfigPage::slotFamilyChanged 4.4 resourcename=%s", standardResource->resourceName().latin1());
246
247
248 Manager<Resource>::Iterator it;
249 for ( it = mCurrentManager->begin(); it != mCurrentManager->end(); ++it ) {
250 ConfigViewItem *item = new ConfigViewItem( mListView, *it );
251 if ( *it == standardResource )
252 item->setStandard( true );
253 }
254
255 if ( mListView->childCount() == 0 ) {
256//US qDebug("ConfigPage::slotFamilyChanged 4.5 ");
257
258 defaults();
259 emit changed( true );
260 mCurrentManager->writeConfig( mCurrentConfig );
261 } else {
262//US qDebug("ConfigPage::slotFamilyChanged 4.6 ");
263
264 if ( !standardResource ) {
265 KMessageBox::sorry( this, i18n( "There is no standard resource! Please select one." ) );
266
267//US qDebug("ConfigPage::slotFamilyChanged 4.7" );
268
269 }
270
271 emit changed( false );
272 }
273}
274
275void ConfigPage::slotAdd()
276{
277 if ( !mCurrentManager )
278 return;
279
280 QStringList types = mCurrentManager->resourceTypeNames();
281 QStringList descs = mCurrentManager->resourceTypeDescriptions();
282 bool ok = false;
283 QString desc = QInputDialog::getItem( i18n( "Resource Configuration" ),
284 i18n( "Please select type of the new resource:" ), descs, 0,
285 false, &ok, this );
286 if ( !ok )
287 return;
288
289 QString type = types[ descs.findIndex( desc ) ];
290
291 // Create new resource
292 Resource *resource = mCurrentManager->createResource( type );
293 if ( !resource ) {
294 KMessageBox::error( this, i18n("Unable to create resource of type '%1'.")
295 .arg( type ) );
296 return;
297 }
298
299 resource->setResourceName( type + "-resource" );
300
301 ConfigDialog dlg( this, mFamily, resource, "KRES::ConfigDialog" );
302
303 if ( dlg.exec() ) {
304 mCurrentManager->add( resource );
305
306 ConfigViewItem *item = new ConfigViewItem( mListView, resource );
307
308 mLastItem = item;
309
310 // if there are only read-only resources we'll set this resource
311 // as standard resource
312 if ( !resource->readOnly() ) {
313 bool onlyReadOnly = true;
314 QListViewItem *it = mListView->firstChild();
315 while ( it != 0 ) {
316 ConfigViewItem *confIt = static_cast<ConfigViewItem*>( it );
317 if ( !confIt->readOnly() && confIt != item )
318 onlyReadOnly = false;
319
320 it = it->itemBelow();
321 }
322
323 if ( onlyReadOnly )
324 item->setStandard( true );
325 }
326
327 emit changed( true );
328 } else {
329 delete resource;
330 resource = 0;
331 }
332}
333
334void ConfigPage::slotRemove()
335{
336 if ( !mCurrentManager )
337 return;
338
339 QListViewItem *item = mListView->currentItem();
340 ConfigViewItem *confItem = static_cast<ConfigViewItem*>( item );
341
342 if ( !confItem )
343 return;
344
345 if ( confItem->standard() ) {
346 KMessageBox::sorry( this, i18n( "You cannot remove your standard resource!\n Please select a new standard resource first." ) );
347 return;
348 }
349
350 mCurrentManager->remove( confItem->resource() );
351
352 if ( item == mLastItem )
353 mLastItem = 0;
354
355 mListView->takeItem( item );
356 delete item;
357
358 emit changed( true );
359}
360
361void ConfigPage::slotEdit()
362{
363 if ( !mCurrentManager )
364 return;
365
366 QListViewItem *item = mListView->currentItem();
367 ConfigViewItem *configItem = static_cast<ConfigViewItem*>( item );
368 if ( !configItem )
369 return;
370
371 Resource *resource = configItem->resource();
372
373 ConfigDialog dlg( this, mFamily, resource, "KRES::ConfigDialog" );
374
375 if ( dlg.exec() ) {
376 configItem->setText( 0, resource->resourceName() );
377 configItem->setText( 1, resource->type() );
378
379 if ( configItem->standard() && configItem->readOnly() ) {
380 KMessageBox::sorry( this, i18n( "You cannot use a read-only resource as standard!" ) );
381 configItem->setStandard( false );
382 }
383
384 mCurrentManager->resourceChanged( resource );
385 emit changed( true );
386 }
387}
388
389void ConfigPage::slotStandard()
390{
391 if ( !mCurrentManager )
392 return;
393
394 ConfigViewItem *item = static_cast<ConfigViewItem*>( mListView->currentItem() );
395 if ( !item )
396 return;
397
398 if ( item->readOnly() ) {
399 KMessageBox::sorry( this, i18n( "You cannot use a read-only resource as standard!" ) );
400 return;
401 }
402
403 if ( !item->isOn() ) {
404 KMessageBox::sorry( this, i18n( "You cannot use an inactive resource as standard!" ) );
405 return;
406 }
407
408 QListViewItem *it = mListView->firstChild();
409 while ( it != 0 ) {
410 ConfigViewItem *configItem = static_cast<ConfigViewItem*>( it );
411 if ( configItem->standard() )
412 configItem->setStandard( false );
413 it = it->itemBelow();
414 }
415
416 item->setStandard( true );
417 mCurrentManager->setStandardResource( item->resource() );
418 emit changed( true );
419
420}
421
422void ConfigPage::slotSelectionChanged()
423{
424 bool state = ( mListView->currentItem() != 0 );
425
426 mRemoveButton->setEnabled( state );
427 mEditButton->setEnabled( state );
428 mStandardButton->setEnabled( state );
429}
430
431void ConfigPage::resourceAdded( Resource* resource )
432{
433 qDebug("ConfigPage::resourceAdded : %s", resource->resourceName().latin1());
434 kdDebug(5650) << "ConfigPage::resourceAdded( " << resource->resourceName() << " )" << endl;
435 ConfigViewItem *item = new ConfigViewItem( mListView, resource );
436
437 // FIXME: this sucks. This should be in the config file,
438 // or application-dependent, in which case it's always Off
439 item->setOn( false );
440
441 mLastItem = item;
442
443 emit changed( true );
444}
445
446void ConfigPage::resourceModified( Resource* resource )
447{
448 qDebug("ConfigPage::resourceModified : %s", resource->resourceName().latin1());
449 kdDebug(5650) << "ConfigPage::resourceModified( " << resource->resourceName() << " )" << endl;
450}
451
452void ConfigPage::resourceDeleted( Resource* resource )
453{
454 qDebug("ConfigPage::resourceDeleted : %s", resource->resourceName().latin1());
455 kdDebug(5650) << "ConfigPage::resourceDeleted( " << resource->resourceName() << " )" << endl;
456}
457
458void ConfigPage::slotItemClicked( QListViewItem *item )
459{
460 ConfigViewItem *configItem = static_cast<ConfigViewItem *>( item );
461 if ( !configItem ) return;
462
463 if ( configItem->standard() && !configItem->isOn() ) {
464 KMessageBox::sorry( this, i18n( "You cannot deactivate the standard resource. Choose another standard resource first." ) );
465 configItem->setOn( true );
466 return;
467 }
468
469 if ( configItem->isOn() != configItem->resource()->isActive() ) {
470 emit changed( true );
471 }
472}
473
474void ConfigPage::saveResourceSettings()
475{
476 qDebug("ConfigPage::saveResourceSettings() begin");
477
478 if ( mCurrentManager ) {
479
480 QListViewItem *item = mListView->firstChild();
481 while ( item ) {
482 ConfigViewItem *configItem = static_cast<ConfigViewItem*>( item );
483
484 // check if standard resource
485 if ( configItem->standard() && !configItem->readOnly() &&
486 configItem->isOn() ) {
487
488 mCurrentManager->setStandardResource( configItem->resource() );
489 }
490
491 // check if active or passive resource
492 configItem->resource()->setActive( configItem->isOn() );
493
494 item = item->nextSibling();
495 }
496 mCurrentManager->writeConfig( mCurrentConfig );
497
498 if ( !mCurrentManager->standardResource() )
499 KMessageBox::sorry( this, i18n( "There is no valid standard resource! Please select one which is neither read-only nor inactive." ) );
500 }
501
502 qDebug("ConfigPage::saveResourceSettings() end");
503
504}
505
506//US #include "configpage.moc"
507
diff --git a/microkde/kresources/configpage.h b/microkde/kresources/configpage.h
new file mode 100644
index 0000000..492ea54
--- a/dev/null
+++ b/microkde/kresources/configpage.h
@@ -0,0 +1,103 @@
1/*
2 This file is part of libkresources.
3 Copyright (c) 2002 Tobias Koenig <tokoe@kde.org>
4 Copyright (c) 2002 Jan-Pascal van Best <janpascal@vanbest.org>
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
15
16 You should have received a copy of the GNU Library General Public License
17 along with this library; see the file COPYING.LIB. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.
20*/
21
22
23#ifndef KRESOURCES_CONFIGPAGE_H
24#define KRESOURCES_CONFIGPAGE_H
25
26#include <qstringlist.h>
27#include <qwidget.h>
28
29#include "manager.h"
30
31class KComboBox;
32class KListView;
33
34class QListViewItem;
35class QPushButton;
36
37
38namespace KRES {
39
40class ResourcePageInfo
41{
42 public:
43 Manager<Resource> *mManager;
44 KConfig *mConfig;
45};
46
47class Resource;
48
49class ConfigPage : public QWidget, public ManagerListener<Resource>
50{
51 Q_OBJECT
52
53 public:
54 ConfigPage( QWidget *parent = 0, const char *name = 0 );
55 virtual ~ConfigPage();
56
57 void load();
58 void save();
59 virtual void defaults();
60
61 public slots:
62 void slotFamilyChanged( int );
63 void slotAdd();
64 void slotRemove();
65 void slotEdit();
66 void slotStandard();
67 void slotSelectionChanged();
68
69 // From ManagerListener<Resource>
70 public:
71 virtual void resourceAdded( Resource* resource );
72 virtual void resourceModified( Resource* resource );
73 virtual void resourceDeleted( Resource* resource );
74
75 protected slots:
76 void slotItemClicked( QListViewItem * );
77
78 signals:
79 void changed( bool );
80
81 private:
82 void saveResourceSettings();
83
84 Manager<Resource>* mCurrentManager;
85 KConfig* mCurrentConfig;
86 KConfig* mConfig;
87 QString mFamily;
88 QStringList mFamilyMap;
89 QValueList<ResourcePageInfo> mInfoMap;
90
91 KComboBox* mFamilyCombo;
92 KListView* mListView;
93 QPushButton* mAddButton;
94 QPushButton* mRemoveButton;
95 QPushButton* mEditButton;
96 QPushButton* mStandardButton;
97
98 QListViewItem* mLastItem;
99};
100
101}
102
103#endif
diff --git a/microkde/kresources/configwidget.cpp b/microkde/kresources/configwidget.cpp
new file mode 100644
index 0000000..c42cbd4
--- a/dev/null
+++ b/microkde/kresources/configwidget.cpp
@@ -0,0 +1,45 @@
1/*
2 This file is part of libkresources.
3
4 Copyright (c) 2002 Tobias Koenig <tokoe@kde.org>
5 Copyright (c) 2002 Jan-Pascal van Best <janpascal@vanbest.org>
6 Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org>
7
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Library General Public
10 License as published by the Free Software Foundation; either
11 version 2 of the License, or (at your option) any later version.
12
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Library General Public License for more details.
17
18 You should have received a copy of the GNU Library General Public License
19 along with this library; see the file COPYING.LIB. If not, write to
20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA.
22*/
23
24#include "configwidget.h"
25
26using namespace KRES;
27
28ConfigWidget::ConfigWidget( QWidget *parent, const char *name )
29 : QWidget( parent, name )
30{
31}
32
33void ConfigWidget::setInEditMode( bool )
34{
35}
36
37void ConfigWidget::loadSettings( Resource * )
38{
39}
40
41void ConfigWidget::saveSettings( Resource * )
42{
43}
44
45//US #include "configwidget.moc"
diff --git a/microkde/kresources/configwidget.h b/microkde/kresources/configwidget.h
new file mode 100644
index 0000000..04dd696
--- a/dev/null
+++ b/microkde/kresources/configwidget.h
@@ -0,0 +1,59 @@
1/*
2 This file is part of libkresources.
3 Copyright (c) 2002 Tobias Koenig <tokoe@kde.org>
4 Copyright (c) 2002 Jan-Pascal van Best <janpascal@vanbest.org>
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
15
16 You should have received a copy of the GNU Library General Public License
17 along with this library; see the file COPYING.LIB. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.
20*/
21
22#ifndef KRESOURCES_CONFIGWIDGET_H
23#define KRESOURCES_CONFIGWIDGET_H
24
25#include <qwidget.h>
26
27#include <kconfig.h>
28
29#include "resource.h"
30
31namespace KRES {
32
33class ConfigWidget : public QWidget
34{
35 Q_OBJECT
36
37public:
38 ConfigWidget( QWidget *parent = 0, const char *name = 0 );
39
40 /**
41 Sets the widget to 'edit' mode. Reimplement this method if you are
42 interested in the mode change (to disable some GUI element for
43 example). By default the widget is in 'create new' mode.
44 */
45 virtual void setInEditMode( bool value );
46
47public slots:
48 virtual void loadSettings( Resource *resource );
49 virtual void saveSettings( Resource *resource );
50
51signals:
52 void setReadOnly( bool value );
53
54protected:
55 Resource* mResource;
56};
57
58}
59#endif
diff --git a/microkde/kresources/factory.cpp b/microkde/kresources/factory.cpp
new file mode 100644
index 0000000..709cd4a
--- a/dev/null
+++ b/microkde/kresources/factory.cpp
@@ -0,0 +1,216 @@
1/*
2 This file is part of libkresources.
3
4 Copyright (c) 2002 Tobias Koenig <tokoe@kde.org>
5 Copyright (c) 2002 Jan-Pascal van Best <janpascal@vanbest.org>
6 Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org>
7
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Library General Public
10 License as published by the Free Software Foundation; either
11 version 2 of the License, or (at your option) any later version.
12
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Library General Public License for more details.
17
18 You should have received a copy of the GNU Library General Public License
19 along with this library; see the file COPYING.LIB. If not, write to
20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA.
22*/
23
24#include <kdebug.h>
25#include <klocale.h>
26#include <ksimpleconfig.h>
27#include <kstandarddirs.h>
28#include <kstaticdeleter.h>
29
30#include <qfile.h>
31
32#include <plugins/file/resourcefile.h>
33#include <plugins/file/resourcefileconfig.h>
34#include <plugins/dir/resourcedir.h>
35#include <plugins/dir/resourcedirconfig.h>
36//#include <plugins/ldap/resourceldap.h>
37//#include <plugins/ldap/resourceldapconfig.h>
38
39
40#include "resource.h"
41#include "factory.h"
42
43using namespace KRES;
44
45QDict<Factory> *Factory::mSelves = 0;
46static KStaticDeleter< QDict<Factory> > staticDeleter;
47
48Factory *Factory::self( const QString& resourceFamily )
49{
50 kdDebug(5650) << "Factory::self()" << endl;
51
52 Factory *factory = 0;
53 if ( !mSelves )
54 {
55 mSelves = staticDeleter.setObject( new QDict<Factory> );
56 }
57
58 factory = mSelves->find( resourceFamily );
59
60 if ( !factory ) {
61 factory = new Factory( resourceFamily );
62 mSelves->insert( resourceFamily, factory );
63 }
64
65 return factory;
66}
67
68Factory::Factory( const QString& resourceFamily ) :
69 mResourceFamily( resourceFamily )
70{
71//US so far we have three types available for resourceFamily "contact"
72// and that are "file", "dir", "ldap"
73/*US
74
75 KTrader::OfferList plugins = KTrader::self()->query( "KResources/Plugin", QString( "[X-KDE-ResourceFamily] == '%1'" )
76 .arg( resourceFamily ) );
77 KTrader::OfferList::ConstIterator it;
78 for ( it = plugins.begin(); it != plugins.end(); ++it ) {
79 QVariant type = (*it)->property( "X-KDE-ResourceType" );
80 if ( !type.toString().isEmpty() )
81 mTypeMap.insert( type.toString(), *it );
82 }
83*/
84
85//US !!!!!!!!!!!!!!!
86 KRES::PluginFactoryBase* pf = (KRES::PluginFactoryBase*)new KRES::PluginFactory<KABC::ResourceFile,KABC::ResourceFileConfig>();
87 mTypeMap.insert( "file", pf );
88
89 pf = (KRES::PluginFactoryBase*)new KRES::PluginFactory<KABC::ResourceDir,KABC::ResourceDirConfig>();
90 mTypeMap.insert( "dir", pf );
91 /*
92 pf = (KRES::PluginFactoryBase*)new KRES::PluginFactory<KABC::ResourceLDAP,KABC::ResourceLDAPConfig>();
93 mTypeMap.insert( "ldap", pf );
94 */
95}
96
97Factory::~Factory()
98{
99}
100
101QStringList Factory::typeNames() const
102{
103//US method QMap::keys() not available yet. SO collect the data manually
104//US return mTypeMap.keys();
105
106 QStringList result;
107
108 QMap<QString, PluginFactoryBase*>::ConstIterator it;
109 for( it = mTypeMap.begin(); it != mTypeMap.end(); ++it ) {
110 result << it.key().latin1();
111// qDebug("Factory::typeNames() : %s ", it.key().latin1());
112
113 }
114 return result;
115}
116
117ConfigWidget *Factory::configWidget( const QString& type, QWidget *parent )
118{
119 if ( type.isEmpty() || !mTypeMap.contains( type ) )
120 return 0;
121
122/*US load the lib not dynamically. !!
123 KService::Ptr ptr = mTypeMap[ type ];
124 KLibFactory *factory = KLibLoader::self()->factory( ptr->library().latin1() );
125 if ( !factory ) {
126 kdDebug() << "KRES::Factory::configWidget(): Factory creation failed" << endl;
127 return 0;
128 }
129*/
130 PluginFactoryBase *factory = mTypeMap[ type ];
131 if ( !factory ) {
132 kdDebug() << "KRES::Factory::configWidget(): Factory creation failed" << endl;
133 return 0;
134 }
135
136
137 PluginFactoryBase *pluginFactory = static_cast<PluginFactoryBase *>( factory );
138
139 if ( !pluginFactory ) {
140 kdDebug() << "KRES::Factory::configWidget(): no plugin factory." << endl;
141 return 0;
142 }
143
144 ConfigWidget *wdg = pluginFactory->configWidget( parent );
145 if ( !wdg ) {
146//US kdDebug() << "'" << ptr->library() << "' is not a " + mResourceFamily + " plugin." << endl;
147 kdDebug() << " is not a " + mResourceFamily + " plugin." << endl;
148 return 0;
149 }
150 return wdg;
151
152}
153
154QString Factory::typeName( const QString &type ) const
155{
156 if ( type.isEmpty() || !mTypeMap.contains( type ) )
157 return QString();
158
159//US KService::Ptr ptr = mTypeMap[ type ];
160//US return ptr->name();
161//US I guess this is correct since we loaded the factory staticly.
162 return type;
163
164}
165
166QString Factory::typeDescription( const QString &type ) const
167{
168 if ( type.isEmpty() || !mTypeMap.contains( type ) )
169 return QString();
170
171//US KService::Ptr ptr = mTypeMap[ type ];
172//US return ptr->comment();
173//US I guess this is correct since we loaded the factory staticly.
174 return type;
175
176}
177
178Resource *Factory::resource( const QString& type, const KConfig *config )
179{
180 kdDebug() << "Factory::resource( " << type << ", config)" << endl;
181
182 if ( type.isEmpty() || !mTypeMap.contains( type ) )
183 return 0;
184
185/*US load the lib not dynamicly. !!
186 KService::Ptr ptr = mTypeMap[ type ];
187 KLibFactory *factory = KLibLoader::self()->factory( ptr->library().latin1() );
188 if ( !factory ) {
189 kdDebug() << "KRES::Factory::resource(): Factory creation failed" << endl;
190 return 0;
191 }
192*/
193 PluginFactoryBase *factory = mTypeMap[ type ];
194 if ( !factory ) {
195 kdDebug() << "KRES::Factory::resource(): Factory creation failed" << endl;
196 return 0;
197 }
198
199 PluginFactoryBase *pluginFactory = static_cast<PluginFactoryBase *>( factory );
200
201 if ( !pluginFactory ) {
202 kdDebug() << "KRES::Factory::resource(): no plugin factory." << endl;
203 return 0;
204 }
205
206 Resource *resource = pluginFactory->resource( config );
207 if ( !resource ) {
208//US kdDebug() << "'" << ptr->library() << "' is not a " + mResourceFamily + " plugin." << endl;
209 kdDebug() << " is not a " + mResourceFamily + " plugin." << endl;
210 return 0;
211 }
212
213 resource->setType( type );
214
215 return resource;
216}
diff --git a/microkde/kresources/factory.h b/microkde/kresources/factory.h
new file mode 100644
index 0000000..f391bb3
--- a/dev/null
+++ b/microkde/kresources/factory.h
@@ -0,0 +1,113 @@
1/*
2 This file is part of libkresources.
3
4 Copyright (c) 2002 Tobias Koenig <tokoe@kde.org>
5 Copyright (c) 2002 Jan-Pascal van Best <janpascal@vanbest.org>
6 Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org>
7
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Library General Public
10 License as published by the Free Software Foundation; either
11 version 2 of the License, or (at your option) any later version.
12
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Library General Public License for more details.
17
18 You should have received a copy of the GNU Library General Public License
19 along with this library; see the file COPYING.LIB. If not, write to
20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA.
22*/
23
24#ifndef KRESOURCES_FACTORY_H
25#define KRESOURCES_FACTORY_H
26
27#include <qdict.h>
28#include <qstring.h>
29
30#include <kconfig.h>
31
32
33#include "resource.h"
34
35namespace KRES {
36
37/**
38 * Class for loading resource plugins.
39 * Do not use this class directly. Use ResourceManager instead
40 *
41 * Example:
42 *
43 * <pre>
44 * KABC::Factory<Calendar> *factory = KABC::Factory<Calendar>::self();
45 *
46 * QStringList list = factory->resources();
47 * QStringList::Iterator it;
48 * for ( it = list.begin(); it != list.end(); ++it ) {
49 * Resource<Calendar> *resource = factory->resource( (*it),
50 * KABC::StdAddressBook::self(), 0 );
51 * // do something with resource
52 * }
53 * </pre>
54 */
55class Factory
56{
57 public:
58
59 /**
60 * Returns the global resource factory.
61 */
62 static Factory *self( const QString& resourceFamily );
63
64 ~Factory();
65
66 /**
67 * Returns the config widget for the given resource type,
68 * or a null pointer if resource type doesn't exist.
69 *
70 * @param type The type of the resource, returned by @ref resources()
71 * @param resource The resource to be editted.
72 * @param parent The parent widget
73 */
74 ConfigWidget *configWidget( const QString& type, QWidget *parent = 0 );
75
76 /**
77 * Returns a pointer to a resource object or a null pointer
78 * if resource type doesn't exist.
79 *
80 * @param type The type of the resource, returned by @ref resources()
81 * @param ab The address book, the resource should belong to
82 * @param config The config object where the resource get it settings from, or 0 if a new resource should be created.
83 */
84 Resource *resource( const QString& type, const KConfig *config );
85
86 /**
87 * Returns a list of all available resource types.
88 */
89 QStringList typeNames() const;
90
91 /**
92 * Returns the name for a special type.
93 */
94 QString typeName( const QString &type ) const;
95
96 /**
97 * Returns the description for a special type.
98 */
99 QString typeDescription( const QString &type ) const;
100
101 protected:
102 Factory( const QString& resourceFamily );
103
104 private:
105 static QDict<Factory> *mSelves;
106
107 QString mResourceFamily;
108//US QMap<QString, KService::Ptr> mTypeMap;
109 QMap<QString, PluginFactoryBase*> mTypeMap;
110};
111
112}
113#endif
diff --git a/microkde/kresources/kcmkresources.cpp b/microkde/kresources/kcmkresources.cpp
new file mode 100644
index 0000000..d600a31
--- a/dev/null
+++ b/microkde/kresources/kcmkresources.cpp
@@ -0,0 +1,89 @@
1/*
2 This file is part of libkresources.
3
4 Copyright (c) 2003 Tobias Koenig <tokoe@kde.org>
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
15
16 You should have received a copy of the GNU Library General Public License
17 along with this library; see the file COPYING.LIB. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.
20*/
21
22#include <qlayout.h>
23
24//US #include <kaboutdata.h>
25//US #include <kgenericfactory.h>
26#include <klocale.h>
27
28#include "configpage.h"
29
30#include "kcmkresources.h"
31
32using namespace KRES;
33
34//US typedef KGenericFactory<KCMKResources, QWidget> ResourcesFactory;
35//US K_EXPORT_COMPONENT_FACTORY( kcm_kresources, ResourcesFactory( "kcmkresources" ) );
36
37//US KCMKResources::KCMKResources( QWidget *parent, const char *name, const QStringList& )
38//US : KCModule( ResourcesFactory::instance(), parent, name )
39KCMKResources::KCMKResources( QWidget *parent, const char *name, const QStringList& )
40 : KDialogBase( parent, name, true, i18n( "Configure Resources" ),
41 Ok|Cancel, Ok, true )
42{
43 QFrame *main = plainPage();
44
45 QVBoxLayout *layout = new QVBoxLayout( main );
46 mConfigPage = new KRES::ConfigPage( main );
47 layout->addWidget( mConfigPage );
48
49
50 connect( mConfigPage, SIGNAL( changed( bool ) ), SLOT( changed( bool ) ) );
51#ifndef DESKTOP_VERSION
52 showMaximized();
53#endif
54}
55
56void KCMKResources::changed( bool changed)
57{
58 modified = changed;
59}
60
61void KCMKResources::slotOk()
62{
63 if (modified) {
64 mConfigPage->save();
65 modified = false;
66 }
67
68 KDialogBase::slotOk();
69}
70
71void KCMKResources::load()
72{
73 qDebug("KCMKResources::load" );
74 mConfigPage->load();
75}
76
77void KCMKResources::save()
78{
79 qDebug("KCMKResources::save" );
80 mConfigPage->save();
81}
82
83void KCMKResources::defaults()
84{
85 qDebug("KCMKResources::defaults" );
86 mConfigPage->defaults();
87}
88
89//US #include "kcmkresources.moc"
diff --git a/microkde/kresources/kcmkresources.h b/microkde/kresources/kcmkresources.h
new file mode 100644
index 0000000..a83bb33
--- a/dev/null
+++ b/microkde/kresources/kcmkresources.h
@@ -0,0 +1,54 @@
1/*
2 This file is part of libkresources.
3
4 Copyright (c) 2003 Tobias Koenig <tokoe@kde.org>
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
15
16 You should have received a copy of the GNU Library General Public License
17 along with this library; see the file COPYING.LIB. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.
20*/
21
22#ifndef KRESOURCES_KCMKRESOURCES_H
23#define KRESOURCES_KCMKRESOURCES_H
24
25#include <kdialogbase.h>
26
27namespace KRES {
28
29class ConfigPage;
30
31
32//US class KCMKResources : public KCModule
33class KCMKResources : public KDialogBase
34{
35 Q_OBJECT
36
37 public:
38 KCMKResources( QWidget *parent, const char *name, const QStringList& );
39
40 void load();
41 void save();
42 void defaults();
43
44 protected slots:
45 virtual void slotOk();
46 void changed( bool );
47
48 private:
49 KRES::ConfigPage *mConfigPage;
50 bool modified;
51};
52
53}
54#endif
diff --git a/microkde/kresources/manager.h b/microkde/kresources/manager.h
new file mode 100644
index 0000000..b5e97fc
--- a/dev/null
+++ b/microkde/kresources/manager.h
@@ -0,0 +1,332 @@
1/*
2 This file is part of libkresources.
3
4 Copyright (c) 2002 Tobias Koenig <tokoe@kde.org>
5 Copyright (c) 2002 Jan-Pascal van Best <janpascal@vanbest.org>
6 Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org>
7
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Library General Public
10 License as published by the Free Software Foundation; either
11 version 2 of the License, or (at your option) any later version.
12
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Library General Public License for more details.
17
18 You should have received a copy of the GNU Library General Public License
19 along with this library; see the file COPYING.LIB. If not, write to
20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA.
22*/
23
24#ifndef KRESOURCES_MANAGER_H
25#define KRESOURCES_MANAGER_H
26
27#include <qdict.h>
28#include <qstringlist.h>
29
30#include "factory.h"
31#include "managerimpl.h"
32
33namespace KRES {
34
35class Resource;
36
37template<class T>
38class ManagerListener
39{
40 public:
41 virtual void resourceAdded( T *resource ) = 0;
42 virtual void resourceModified( T *resource ) = 0;
43 virtual void resourceDeleted( T *resource ) = 0;
44};
45
46// TODO:
47// The resource manager should provide some signals
48// to warn applications that resources have been added,
49// removed or modified.
50//
51// The manager should also keep track of which (or at least
52// how many) applications hve opened a resource, so that it
53// is only closed if none of them is using it any more
54
55template<class T>
56class Manager : private ManagerImplListener
57{
58 public:
59 class Iterator
60 {
61 friend class Manager;
62 public:
63 Iterator() {};
64 Iterator( const Iterator &it ) { mIt = it.mIt; }
65
66 T *operator*() { return static_cast<T *>( *mIt ); }
67 Iterator &operator++() { mIt++; return *this; }
68 Iterator &operator++(int) { mIt++; return *this; }
69 Iterator &operator--() { mIt--; return *this; }
70 Iterator &operator--(int) { mIt--; return *this; }
71 bool operator==( const Iterator &it ) { return mIt == it.mIt; }
72 bool operator!=( const Iterator &it ) { return mIt != it.mIt; }
73
74 private:
75 Resource::List::Iterator mIt;
76 };
77
78 Iterator begin()
79 {
80 Iterator it;
81 it.mIt = mImpl->resourceList()->begin();
82 return it;
83 }
84
85 Iterator end()
86 {
87 Iterator it;
88 it.mIt = mImpl->resourceList()->end();
89 return it;
90 }
91
92 class ActiveIterator
93 {
94 friend class Manager;
95 public:
96 ActiveIterator() : mList( 0 ) {};
97 ActiveIterator( const ActiveIterator &it )
98 {
99 mIt = it.mIt;
100 mList = it.mList;
101 }
102
103 T *operator*() { return static_cast<T *>( *mIt ); }
104 ActiveIterator &operator++()
105 {
106 do { mIt++; } while ( checkActive() );
107 return *this;
108 }
109 ActiveIterator &operator++(int)
110 {
111 do { mIt++; } while ( checkActive() );
112 return *this;
113 }
114 ActiveIterator &operator--()
115 {
116 do { mIt--; } while ( checkActive() );
117 return *this;
118 }
119 ActiveIterator &operator--(int)
120 {
121 do { mIt--; } while ( checkActive() );
122 return *this;
123 }
124 bool operator==( const ActiveIterator &it ) { return mIt == it.mIt; }
125 bool operator!=( const ActiveIterator &it ) { return mIt != it.mIt; }
126
127 private:
128 /**
129 Check if iterator needs to be advanced once more.
130 */
131 bool checkActive()
132 {
133 if ( !mList || mIt == mList->end() ) return false;
134 return !(*mIt)->isActive();
135 }
136
137 Resource::List::Iterator mIt;
138 Resource::List *mList;
139 };
140
141 ActiveIterator activeBegin()
142 {
143 ActiveIterator it;
144 it.mIt = mImpl->resourceList()->begin();
145 it.mList = mImpl->resourceList();
146 if ( it.mIt != mImpl->resourceList()->end() ) {
147 if ( !(*it)->isActive() ) it++;
148 }
149 return it;
150 }
151
152 ActiveIterator activeEnd()
153 {
154 ActiveIterator it;
155 it.mIt = mImpl->resourceList()->end();
156 it.mList = mImpl->resourceList();
157 return it;
158 }
159
160 bool isEmpty() const { return mImpl->resourceList()->isEmpty(); }
161
162 Manager( const QString &family )
163 {
164 mFactory = Factory::self( family );
165 // The managerimpl will use the same Factory object as the manager
166 // because of the Factory::self() pattern
167 mImpl = new ManagerImpl( family );
168 mImpl->setListener( this );
169
170 mListeners = new QPtrList<ManagerListener<T> >;
171 }
172
173 virtual ~Manager()
174 {
175 mImpl->setListener( 0 );
176 delete mListeners;
177 delete mImpl;
178 }
179
180 /**
181 Recreate Resource objects from configuration file. If cfg is 0, read standard
182 configuration file.
183 */
184 void readConfig( KConfig *cfg = 0 )
185 {
186 mImpl->readConfig( cfg );
187 }
188
189 /**
190 Write configuration of Resource objects to configuration file. If cfg is 0, write
191 to standard configuration file.
192 */
193 void writeConfig( KConfig *cfg = 0 )
194 {
195 mImpl->writeConfig( cfg );
196 }
197
198 /**
199 Add resource to manager. This passes ownership of the Resource object
200 to the manager.
201 */
202 void add( Resource *resource )
203 {
204 if ( resource ) mImpl->add( resource );
205 }
206
207 void remove( Resource *resource )
208 {
209 if ( resource ) mImpl->remove( resource );
210 }
211
212 T* standardResource()
213 {
214 return static_cast<T *>( mImpl->standardResource() );
215 }
216
217 void setStandardResource( T *resource )
218 {
219 if ( resource ) mImpl->setStandardResource( resource );
220 }
221
222 void setActive( Resource *resource, bool active )
223 {
224 if ( resource ) mImpl->setActive( resource, active );
225 }
226
227 /**
228 Returns a list of the names of the reources managed by the
229 Manager for this family.
230 */
231 QStringList resourceNames() const
232 {
233 return mImpl->resourceNames();
234 }
235
236 ConfigWidget *configWidget( const QString& type, QWidget *parent = 0 )
237 {
238 return mFactory->resourceConfigWidget( type, parent );
239 }
240
241 /**
242 Creates a new resource of type @param type, with default
243 settings. The resource is
244 not added to the manager, the application has to do that.
245 Returns a pointer to a resource object or a null pointer
246 if resource type doesn't exist.
247
248 @param type The type of the resource, one of those returned
249 by @ref resourceTypeNames()
250 */
251 T *createResource( const QString& type )
252 {
253 return (T *)( mFactory->resource( type, 0 ) );
254 }
255
256 /**
257 Returns a list of the names of all available resource types.
258 */
259 QStringList resourceTypeNames() const
260 {
261 return mFactory->typeNames();
262 }
263
264 QStringList resourceTypeDescriptions() const
265 {
266 QStringList typeDescs;
267 QStringList types = mFactory->typeNames();
268
269 for ( QStringList::ConstIterator it = types.begin(); it != types.end(); ++it ) {
270 QString desc = mFactory->typeName( *it );
271 if ( !mFactory->typeDescription( *it ).isEmpty() )
272 desc += " (" + mFactory->typeDescription( *it ) + ")";
273
274 typeDescs.append( desc );
275 }
276
277 return typeDescs;
278 }
279
280 void resourceChanged( T *resource )
281 {
282 mImpl->resourceChanged( resource );
283 }
284
285 void addListener( ManagerListener<T> *listener )
286 {
287 mListeners->append( listener );
288 }
289
290 void removeListener( ManagerListener<T> *listener )
291 {
292 mListeners->remove( listener );
293 }
294
295 virtual void resourceAdded( Resource *res )
296 {
297 kdDebug(5650) << "Manager::resourceAdded " << res->resourceName() << endl;
298 T* resource = (T *)( res );
299 ManagerListener<T> *listener;
300 for ( listener = mListeners->first(); listener; listener = mListeners->next() )
301 listener->resourceAdded( resource );
302 }
303
304 virtual void resourceModified( Resource *res )
305 {
306 kdDebug(5650) << "Manager::resourceModified " << res->resourceName() << endl;
307 T* resource = (T *)( res );
308 ManagerListener<T> *listener;
309 for ( listener = mListeners->first(); listener; listener = mListeners->next() )
310 listener->resourceModified( resource );
311 }
312
313 virtual void resourceDeleted( Resource *res )
314 {
315 kdDebug(5650) << "Manager::resourceDeleted " << res->resourceName() << endl;
316 T* resource = (T *)( res );
317 ManagerListener<T> *listener;
318 for ( listener = mListeners->first(); listener; listener = mListeners->next() ) {
319 kdDebug(5650) << "Notifying a listener to Manager..." << endl;
320 listener->resourceDeleted( resource );
321 }
322 }
323
324 private:
325 ManagerImpl *mImpl;
326 Factory *mFactory;
327 QPtrList<ManagerListener<T> > *mListeners;
328};
329
330}
331
332#endif
diff --git a/microkde/kresources/managerimpl.cpp b/microkde/kresources/managerimpl.cpp
new file mode 100644
index 0000000..1baa6be
--- a/dev/null
+++ b/microkde/kresources/managerimpl.cpp
@@ -0,0 +1,353 @@
1/*
2 This file is part of libkresources.
3
4 Copyright (c) 2002 Tobias Koenig <tokoe@kde.org>
5 Copyright (c) 2002 Jan-Pascal van Best <janpascal@vanbest.org>
6 Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org>
7
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Library General Public
10 License as published by the Free Software Foundation; either
11 version 2 of the License, or (at your option) any later version.
12
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Library General Public License for more details.
17
18 You should have received a copy of the GNU Library General Public License
19 along with this library; see the file COPYING.LIB. If not, write to
20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA.
22*/
23
24#include <kglobal.h>
25
26#include <kapplication.h>
27#include <kdebug.h>
28#include <kconfig.h>
29#include <kstandarddirs.h>
30
31#include "resource.h"
32#include "factory.h"
33#include "managerimpl.h"
34
35using namespace KRES;
36
37ManagerImpl::ManagerImpl( const QString &family )
38 : mFamily( family ), mConfig( 0 ), mStdConfig( 0 ), mStandard( 0 ),
39 mFactory( 0 )
40
41{
42 kdDebug(5650) << "ManagerImpl::ManagerImpl()" << endl;
43
44
45}
46
47ManagerImpl::~ManagerImpl()
48{
49 kdDebug(5650) << "ManagerImpl::~ManagerImpl()" << endl;
50
51 Resource::List::ConstIterator it;
52 for ( it = mResources.begin(); it != mResources.end(); ++it ) {
53 delete *it;
54 }
55
56 delete mStdConfig;
57}
58
59void ManagerImpl::createStandardConfig()
60{
61 if ( !mStdConfig ) {
62 QString file = locateLocal( "data", KGlobal::getAppName()
63 + "/kresources/" + mFamily + "rc" );
64 mStdConfig = new KConfig( file );
65 }
66
67 mConfig = mStdConfig;
68}
69
70void ManagerImpl::readConfig( KConfig *cfg )
71{
72 kdDebug(5650) << "ManagerImpl::readConfig()" << endl;
73
74 delete mFactory;
75 mFactory = Factory::self( mFamily );
76
77 if ( !cfg ) {
78 createStandardConfig();
79 } else {
80 mConfig = cfg;
81 }
82
83 mStandard = 0;
84
85 mConfig->setGroup( "General" );
86
87 QStringList keys = mConfig->readListEntry( "ResourceKeys" );
88 keys += mConfig->readListEntry( "PassiveResourceKeys" );
89
90 QString standardKey = mConfig->readEntry( "Standard" );
91
92 for ( QStringList::Iterator it = keys.begin(); it != keys.end(); ++it ) {
93 readResourceConfig( *it, false );
94 }
95
96}
97
98void ManagerImpl::writeConfig( KConfig *cfg )
99{
100//USqDebug("ManagerImpl::writeConfig begin this= %ul cfg=%ul", this, cfg);
101
102
103 kdDebug(5650) << "ManagerImpl::writeConfig()" << endl;
104
105 if ( !cfg ) {
106 createStandardConfig();
107 } else {
108 mConfig = cfg;
109 }
110
111 QStringList activeKeys;
112 QStringList passiveKeys;
113
114 // First write all keys, collect active and passive keys on the way
115 Resource::List::Iterator it;
116 for ( it = mResources.begin(); it != mResources.end(); ++it ) {
117 writeResourceConfig( *it, false );
118
119 QString key = (*it)->identifier();
120 if( (*it)->isActive() )
121 activeKeys.append( key );
122 else
123 passiveKeys.append( key );
124 }
125
126 // And then the general group
127
128 kdDebug(5650) << "Saving general info" << endl;
129 mConfig->setGroup( "General" );
130 mConfig->writeEntry( "ResourceKeys", activeKeys );
131 mConfig->writeEntry( "PassiveResourceKeys", passiveKeys );
132 if ( mStandard )
133 mConfig->writeEntry( "Standard", mStandard->identifier() );
134 else
135 mConfig->writeEntry( "Standard", "" );
136
137 mConfig->sync();
138 kdDebug(5650) << "ManagerImpl::save() finished" << endl;
139
140//US qDebug("ManagerImpl::writeConfig end this= %ul cfg=%ul", this, cfg);
141
142}
143
144void ManagerImpl::add( Resource *resource, bool useDCOP )
145{
146qDebug("ManagerImpl::add begin this= %ul resource=%ul", this, resource);
147
148 resource->setActive( true );
149
150 if ( mResources.isEmpty() ) {
151 mStandard = resource;
152 }
153
154 mResources.append( resource );
155
156 writeResourceConfig( resource, true );
157
158 qDebug("ManagerImpl::add end this= %ul resource=%ul", this, resource);
159
160}
161
162void ManagerImpl::remove( Resource *resource, bool useDCOP )
163{
164 if ( mStandard == resource ) mStandard = 0;
165 removeResource( resource );
166
167 mResources.remove( resource );
168
169 delete resource;
170
171 kdDebug(5650) << "Finished ManagerImpl::remove()" << endl;
172}
173
174void ManagerImpl::setActive( Resource *resource, bool active )
175{
176 if ( resource && resource->isActive() != active ) {
177 resource->setActive( active );
178 }
179}
180
181Resource *ManagerImpl::standardResource()
182{
183 return mStandard;
184}
185
186void ManagerImpl::setStandardResource( Resource *resource )
187{
188 mStandard = resource;
189}
190
191void ManagerImpl::resourceChanged( Resource *resource )
192{
193 writeResourceConfig( resource, true );
194
195
196// ManagerIface_stub allManagers( "*", "ManagerIface_" + mFamily.utf8() );
197// allManagers.dcopResourceModified( resource->identifier() );
198}
199
200// DCOP asynchronous functions
201//US since we work from inside the application, we call the methods directly.
202
203QStringList ManagerImpl::resourceNames()
204{
205 QStringList result;
206
207 Resource::List::ConstIterator it;
208 for ( it = mResources.begin(); it != mResources.end(); ++it ) {
209 result.append( (*it)->resourceName() );
210 }
211 return result;
212}
213
214Resource::List *ManagerImpl::resourceList()
215{
216 return &mResources;
217}
218
219QPtrList<Resource> ManagerImpl::resources()
220{
221 QPtrList<Resource> result;
222
223 Resource::List::ConstIterator it;
224 for ( it = mResources.begin(); it != mResources.end(); ++it ) {
225 result.append( *it );
226 }
227 return result;
228}
229
230QPtrList<Resource> ManagerImpl::resources( bool active )
231{
232 QPtrList<Resource> result;
233
234 Resource::List::ConstIterator it;
235 for ( it = mResources.begin(); it != mResources.end(); ++it ) {
236 if ( (*it)->isActive() == active ) {
237 result.append( *it );
238 }
239 }
240 return result;
241}
242
243void ManagerImpl::setListener( ManagerImplListener *listener )
244{
245 mListener = listener;
246}
247
248Resource* ManagerImpl::readResourceConfig( const QString& identifier,
249 bool checkActive )
250{
251 kdDebug() << "ManagerImpl::readResourceConfig() " << identifier << endl;
252
253// qDebug("ManagerImpl::readResourceConfig() %s", identifier.latin1());
254
255 mConfig->setGroup( "Resource_" + identifier );
256
257 QString type = mConfig->readEntry( "ResourceType" );
258 QString name = mConfig->readEntry( "ResourceName" );
259 Resource *resource = mFactory->resource( type, mConfig );
260 if ( !resource ) {
261 kdDebug(5650) << "Failed to create resource with id " << identifier << endl;
262 return 0;
263 }
264
265 if ( resource->identifier().isEmpty() )
266 resource->setIdentifier( identifier );
267
268 mConfig->setGroup( "General" );
269
270 QString standardKey = mConfig->readEntry( "Standard" );
271 if ( standardKey == identifier ) {
272 mStandard = resource;
273 }
274
275 if ( checkActive ) {
276 QStringList activeKeys = mConfig->readListEntry( "ResourceKeys" );
277 resource->setActive( activeKeys.contains( identifier ) );
278 }
279 mResources.append( resource );
280
281 return resource;
282}
283
284void ManagerImpl::writeResourceConfig( Resource *resource,
285 bool checkActive )
286{
287 QString key = resource->identifier();
288
289 kdDebug(5650) << "Saving resource " << key << endl;
290
291 if ( !mConfig ) createStandardConfig();
292
293 mConfig->setGroup( "Resource_" + key );
294 resource->writeConfig( mConfig );
295
296 mConfig->setGroup( "General" );
297 QString standardKey = mConfig->readEntry( "Standard" );
298
299 if ( resource == mStandard && standardKey != key )
300 mConfig->writeEntry( "Standard", resource->identifier() );
301 else if ( resource != mStandard && standardKey == key )
302 mConfig->writeEntry( "Standard", "" );
303
304 if ( checkActive ) {
305 QStringList activeKeys = mConfig->readListEntry( "ResourceKeys" );
306 if ( resource->isActive() && !activeKeys.contains( key ) ) {
307 activeKeys.append( resource->identifier() );
308 mConfig->writeEntry( "ResourceKeys", activeKeys );
309 } else if ( !resource->isActive() && activeKeys.contains( key ) ) {
310 activeKeys.remove( key );
311 mConfig->writeEntry( "ResourceKeys", activeKeys );
312 }
313 }
314
315 mConfig->sync();
316}
317
318void ManagerImpl::removeResource( Resource *resource )
319{
320 QString key = resource->identifier();
321
322 if ( !mConfig ) createStandardConfig();
323
324 mConfig->setGroup( "General" );
325 QStringList activeKeys = mConfig->readListEntry( "ResourceKeys" );
326 if ( activeKeys.contains( key ) ) {
327 activeKeys.remove( key );
328 mConfig->writeEntry( "ResourceKeys", activeKeys );
329 } else {
330 QStringList passiveKeys = mConfig->readListEntry( "PassiveResourceKeys" );
331 passiveKeys.remove( key );
332 mConfig->writeEntry( "PassiveResourceKeys", passiveKeys );
333 }
334
335 QString standardKey = mConfig->readEntry( "Standard" );
336 if ( standardKey == key ) {
337 mConfig->writeEntry( "Standard", "" );
338 }
339
340 mConfig->deleteGroup( "Resource_" + resource->identifier() );
341
342 mConfig->sync();
343}
344
345Resource* ManagerImpl::getResource( const QString& identifier )
346{
347 Resource::List::ConstIterator it;
348 for ( it = mResources.begin(); it != mResources.end(); ++it ) {
349 if ( (*it)->identifier() == identifier )
350 return *it;
351 }
352 return 0;
353}
diff --git a/microkde/kresources/managerimpl.h b/microkde/kresources/managerimpl.h
new file mode 100644
index 0000000..a049bcc
--- a/dev/null
+++ b/microkde/kresources/managerimpl.h
@@ -0,0 +1,113 @@
1/*
2 This file is part of libkresources.
3
4 Copyright (c) 2002 Tobias Koenig <tokoe@kde.org>
5 Copyright (c) 2002 Jan-Pascal van Best <janpascal@vanbest.org>
6 Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org>
7
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Library General Public
10 License as published by the Free Software Foundation; either
11 version 2 of the License, or (at your option) any later version.
12
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Library General Public License for more details.
17
18 You should have received a copy of the GNU Library General Public License
19 along with this library; see the file COPYING.LIB. If not, write to
20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA.
22*/
23
24#ifndef KRESOURCES_MANAGERIMPL_H
25#define KRESOURCES_MANAGERIMPL_H
26
27#include <qstring.h>
28#include <qptrlist.h>
29#include <qdict.h>
30//US
31#include <qobject.h>
32
33#include "resource.h"
34
35
36class KConfig;
37
38namespace KRES {
39
40class Resource;
41class Factory;
42
43class ManagerImplListener
44{
45 public:
46 virtual void resourceAdded( Resource *resource ) = 0;
47 virtual void resourceModified( Resource *resource ) = 0;
48 virtual void resourceDeleted( Resource *resource ) = 0;
49};
50
51
52/**
53 @internal
54
55 Do not use this class directly. Use ResourceManager instead
56*/
57class ManagerImpl : public QObject
58{
59 Q_OBJECT
60 public:
61 ManagerImpl( const QString &family );
62 ~ManagerImpl();
63
64 void readConfig( KConfig * );
65 void writeConfig( KConfig * );
66
67 void add( Resource *resource, bool useDCOP = true );
68 void remove( Resource *resource, bool useDCOP = true );
69
70 Resource *standardResource();
71 void setStandardResource( Resource *resource );
72
73 void setActive( Resource *resource, bool active );
74
75 Resource::List *resourceList();
76
77 QPtrList<Resource> resources();
78
79 // Get only active or passive resources
80 QPtrList<Resource> resources( bool active );
81
82 QStringList resourceNames();
83
84 void setListener( ManagerImplListener *listener );
85
86 public slots:
87 void resourceChanged( Resource *resource );
88
89 private:
90 // dcop calls
91
92 private:
93 void createStandardConfig();
94
95 Resource *readResourceConfig( const QString& identifier, bool checkActive );
96 void writeResourceConfig( Resource *resource, bool checkActive );
97
98 void removeResource( Resource *resource );
99 Resource *getResource( Resource *resource );
100 Resource *getResource( const QString& identifier );
101
102 QString mFamily;
103 KConfig *mConfig;
104 KConfig *mStdConfig;
105 Resource *mStandard;
106 Factory *mFactory;
107 Resource::List mResources;
108 ManagerImplListener *mListener;
109};
110
111}
112
113#endif
diff --git a/microkde/kresources/resource.cpp b/microkde/kresources/resource.cpp
new file mode 100644
index 0000000..169eaa4
--- a/dev/null
+++ b/microkde/kresources/resource.cpp
@@ -0,0 +1,185 @@
1/*
2 This file is part of libkresources.
3
4 Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
5 Copyright (c) 2002 Jan-Pascal van Best <janpascal@vanbest.org>
6 Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org>
7
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Library General Public
10 License as published by the Free Software Foundation; either
11 version 2 of the License, or (at your option) any later version.
12
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Library General Public License for more details.
17
18 You should have received a copy of the GNU Library General Public License
19 along with this library; see the file COPYING.LIB. If not, write to
20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA.
22*/
23
24#include <kdebug.h>
25#include <kapplication.h>
26#include <kconfig.h>
27
28#include "resource.h"
29
30using namespace KRES;
31
32class Resource::ResourcePrivate
33{
34 public:
35#ifdef QT_THREAD_SUPPORT
36 QMutex mMutex;
37#endif
38 int mOpenCount;
39 QString mType;
40 QString mIdentifier;
41 bool mReadOnly;
42 QString mName;
43 bool mActive;
44 bool mIsOpen;
45};
46
47Resource::Resource( const KConfig* config )
48 : QObject( 0, "" ), d( new ResourcePrivate )
49{
50 d->mOpenCount = 0;
51 d->mIsOpen = false;
52
53 //US compiler claimed that const discards qualifier
54 KConfig* cfg = (KConfig*)config;
55 if ( cfg ) {
56 d->mType = cfg->readEntry( "ResourceType" );
57 d->mName = cfg->readEntry( "ResourceName" );
58 d->mReadOnly = cfg->readBoolEntry( "ResourceIsReadOnly", false );
59 d->mActive = cfg->readBoolEntry( "ResourceIsActive", true );
60 d->mIdentifier = cfg->readEntry( "ResourceIdentifier" );
61 } else {
62 d->mType = "type";
63 d->mName = "resource-name";
64 d->mReadOnly = false;
65 d->mActive = true;
66 d->mIdentifier = KApplication::randomString( 10 );
67 }
68}
69
70Resource::~Resource()
71{
72 delete d;
73 d = 0;
74}
75
76void Resource::writeConfig( KConfig* config )
77{
78 kdDebug(5650) << "Resource::writeConfig()" << endl;
79
80 config->writeEntry( "ResourceType", d->mType );
81 config->writeEntry( "ResourceName", d->mName );
82 config->writeEntry( "ResourceIsReadOnly", d->mReadOnly );
83 config->writeEntry( "ResourceIsActive", d->mActive );
84 config->writeEntry( "ResourceIdentifier", d->mIdentifier );
85}
86
87bool Resource::open()
88{
89 d->mIsOpen = true;
90#ifdef QT_THREAD_SUPPORT
91 QMutexLocker guard( &(d->mMutex) );
92#endif
93 if ( !d->mOpenCount ) {
94 kdDebug(5650) << "Opening resource " << resourceName() << endl;
95 d->mIsOpen = doOpen();
96 }
97 d->mOpenCount++;
98 return d->mIsOpen;
99}
100
101void Resource::close()
102{
103#ifdef QT_THREAD_SUPPORT
104 QMutexLocker guard( &(d->mMutex) );
105#endif
106 if ( !d->mOpenCount ) {
107 kdDebug(5650) << "ERROR: Resource " << resourceName() << " closed more times than previously opened" << endl;
108 return;
109 }
110 d->mOpenCount--;
111 if ( !d->mOpenCount ) {
112 kdDebug(5650) << "Closing resource " << resourceName() << endl;
113 doClose();
114 d->mIsOpen = false;
115 } else {
116 kdDebug(5650) << "Not yet closing resource " << resourceName() << ", open count = " << d->mOpenCount << endl;
117 }
118}
119
120bool Resource::isOpen() const
121{
122 return d->mIsOpen;
123}
124
125void Resource::setIdentifier( const QString& identifier )
126{
127 d->mIdentifier = identifier;
128}
129
130QString Resource::identifier() const
131{
132 return d->mIdentifier;
133}
134
135void Resource::setType( const QString& type )
136{
137 d->mType = type;
138}
139
140QString Resource::type() const
141{
142 return d->mType;
143}
144
145void Resource::setReadOnly( bool value )
146{
147 d->mReadOnly = value;
148}
149
150bool Resource::readOnly() const
151{
152 return d->mReadOnly;
153}
154
155void Resource::setResourceName( const QString &name )
156{
157 d->mName = name;
158}
159
160QString Resource::resourceName() const
161{
162 return d->mName;
163}
164
165void Resource::setActive( bool value )
166{
167 d->mActive = value;
168}
169
170bool Resource::isActive() const
171{
172 return d->mActive;
173}
174
175void Resource::dump() const
176{
177 kdDebug(5650) << "Resource:" << endl;
178 kdDebug(5650) << " Name: " << d->mName << endl;
179 kdDebug(5650) << " Identifier: " << d->mIdentifier << endl;
180 kdDebug(5650) << " Type: " << d->mType << endl;
181 kdDebug(5650) << " OpenCount: " << d->mOpenCount << endl;
182 kdDebug(5650) << " ReadOnly: " << ( d->mReadOnly ? "yes" : "no" ) << endl;
183 kdDebug(5650) << " Active: " << ( d->mActive ? "yes" : "no" ) << endl;
184 kdDebug(5650) << " IsOpen: " << ( d->mIsOpen ? "yes" : "no" ) << endl;
185}
diff --git a/microkde/kresources/resource.h b/microkde/kresources/resource.h
new file mode 100644
index 0000000..7ff4f23
--- a/dev/null
+++ b/microkde/kresources/resource.h
@@ -0,0 +1,401 @@
1/*
2 This file is part of libkresources
3
4 Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
5 Copyright (c) 2002 Jan-Pascal van Best <janpascal@vanbest.org>
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Library General Public
9 License as published by the Free Software Foundation; either
10 version 2 of the License, or (at your option) any later version.
11
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Library General Public License for more details.
16
17 You should have received a copy of the GNU Library General Public License
18 along with this library; see the file COPYING.LIB. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.
21*/
22
23#ifndef KRESOURCES_RESOURCE_H
24#define KRESOURCES_RESOURCE_H
25
26//US
27#ifdef QT_THREAD_SUPPORT
28#include <qmutex.h>
29#endif //QT_THREAD_SUPPORT
30
31#include <qvaluelist.h>
32#include <qwidget.h>
33
34#include <qobject.h>
35
36class KConfig;
37
38namespace KRES {
39
40class KLibFactory;
41class ConfigWidget;
42
43/**
44 * @internal
45 * @libdoc The KDE Resource library
46 *
47 * NOTE: this library is NOT (YET?) PUBLIC. Do not publish this
48 * interface, it is in constant flux.
49 *
50 * The KDE Resource framework can be used to manage resources of
51 * different types, organized in families. The Resource framework
52 * is currently used for addressbook resources in libkabc and for
53 * calendar resources in libkcal.
54 *
55 * When you want to use the framework for a new family, you need to
56 * <ul><li>Define a name for your resource family</li>
57 * <li>subclass Resource and add the fields and method that are needed
58 * in your application</li>
59 * <li>If needed, override the doOpen() and doClose() methods.
60 * <li> Provide a configuration possibility for resources in your
61 * new family. You can use @ref ResourcesConfigPage to easily create a
62 * KControl applet</li>
63 * <li>In your application, you can use @ref ResourceManager to keep track
64 * of the resources in your family, and you can use @ref ResourceSelectDialog
65 * to let the user select a single resource.</li>
66 * </ul>
67 *
68 * When you want to add a new resource type to an existing resource family,
69 * you need to
70 * <ul><li>Further subclass the family-specific Resource to implement
71 * resource type-specific operation</li>
72 * <li>Subclass ResourceConfigWidget to provide a configuration widget
73 * for your new resource type</li>
74 * <li>Provide a .desktop file so that the new resource type can be found
75 * automatically by the ResourceManager</li>
76 * </ul>
77 *
78 * Example:
79 *
80<B>resourceexample.h</B>:
81<pre>
82#include <kconfig.h>
83#include <kresources/resource.h>
84
85class ResourceExample : public KRES::ResourceExample
86{
87public:
88 ResourceExample( const KConfig * );
89 ~ResourceCalendarExchange();
90 void writeConfig( KConfig *config );
91private:
92 QString mLocation;
93 QString mPassword;
94}
95</pre>
96<B>resourceexample.cpp</B>:
97<pre>
98#include <kconfig.h>
99
100#include "resourceexample.h"
101
102ResourceExample::ResourceExample( const KConfig *config )
103 : Resource( config )
104{
105 if ( config ) {
106 mLocation = config->readEntry( "Location" );
107 mPassword = KStringHandler::obscure( config->readEntry( "Password" ) );
108 } else {
109 mLocation = ""; // Or some sensible default
110 mPassword = "";
111 }
112}
113
114void ResourceExample::writeConfig( KConfig *config )
115{
116 KRES::Resource::writeConfig( config );
117 config->writeEntry( "Location", mLocation );
118 config->writeEntry( "Password", KStringHandler::obscure( mPassword ) );
119}
120
121extern "C"
122{
123 KRES::ResourceExample *config_widget( QWidget *parent ) {
124 return new ResourceExampleConfig( parent, "Configure Example Resource" );
125 }
126
127 KRES::Resource *resource( const KConfig *config ) {
128 return new ResourceExample( config );
129 }
130}
131</pre>
132* <B>resourceexampleconfig.h</B>:
133<pre>
134#include <klineedit.h>
135#include <kresources/resourceconfigwidget.h>
136
137#include "resourceexample.h"
138
139class ResourceExampleConfig : public KRES::ResourceConfigWidget
140{
141 Q_OBJECT
142
143public:
144 ResourceExampleConfig( QWidget* parent = 0, const char* name = 0 );
145
146public slots:
147 virtual void loadSettings( KRES::Resource *resource);
148 virtual void saveSettings( KRES::Resource *resource );
149
150private:
151 KLineEdit* mLocationEdit;
152 KLineEdit* mPasswordEdit;
153};
154</pre>
155* <B>resourceexampleconfig.cpp</B>:
156<pre>
157#include <qlayout.h>
158#include <qlabel.h"
159#include <kresources/resourceconfigwidget.h>
160#include "resourceexample.h"
161#include "resourceexampleconfig.h"
162
163ResourceExampleConfig::ResourceExampleConfig( QWidget* parent, const char* name )
164 : KRES::ResourceConfigWidget( parent, name )
165{
166 resize( 245, 115 );
167 QGridLayout *mainLayout = new QGridLayout( this, 2, 2 );
168
169 QLabel *label = new QLabel( i18n( "Location:" ), this );
170 mHostEdit = new KLineEdit( this );
171 mainLayout->addWidget( label, 1, 0 );
172 mainLayout->addWidget( mHostEdit, 1, 1 );
173
174 label = new QLabel( i18n( "Password:" ), this );
175 mPasswordEdit = new KLineEdit( this );
176 mPasswordEdit->setEchoMode( QLineEdit::Password );
177 mainLayout->addWidget( label, 2, 0 );
178 mainLayout->addWidget( mPasswordEdit, 2, 1 );
179}
180
181void ResourceExampleConfig::loadSettings( KRES::Resource *resource )
182{
183 ResourceExample* res = dynamic_cast<ResourceExample *>( resource );
184 if (res) {
185 mHostEdit->setText( res->host() );
186 mPasswordEdit->setText( res->password() );
187 } else
188 kdDebug(5700) << "ERROR: ResourceExampleConfig::loadSettings(): no ResourceExample, cast failed" << endl;
189}
190
191void ResourceExampleConfig::saveSettings( KRES::Resource *resource )
192{
193 ResourceExample* res = dynamic_cast<ResourceExample *>( resource );
194 if (res) {
195 res->setHost(mHostEdit->text());
196 res->setPassword(mPasswordEdit->text());
197 } else
198 kdDebug(5700) << "ERROR: ResourceExampleConfig::saveSettings(): no ResourceExample, cast failed" << endl;
199}
200</pre>
201* <B>resourceexample.desktop</B>:
202<pre>
203[Desktop Entry]
204Type=Service
205
206[Misc]
207Encoding=UTF-8
208Name=Example Resource
209
210[Plugin]
211Type=exchange
212X-KDE-Library=resourceexample
213</pre>
214* <B>Makefile.am</B>
215<pre>
216kde_module_LTLIBRARIES = resourceexample.la
217
218resourceexample_la_SOURCES = resourceexample.cpp resourceexampleconfig.cpp
219resourceexample_la_LDFLAGS= $(all_libraries) -module $(KDE_PLUGIN)
220resourceexample_la_LIBADD= -lkderesources
221
222linkdir= $(kde_datadir)/resources/family
223link_DATA= resourceexample.desktop
224</pre>
225 *
226 *
227 */
228
229/**
230 * A @ref Resource is a ...
231 *
232 * A subclass should reimplement at least the constructor and the
233 * @ref writeConfig method.
234 *
235 */
236class Resource : public QObject
237{
238 Q_OBJECT
239
240 public:
241 typedef QValueList<Resource *> List;
242
243 /**
244 * Constructor. Construct resource from config.
245 * @param config Configuration to read persistence information from.
246 * If config==0, create object using default settings.
247 */
248 Resource( const KConfig* config );
249
250 /**
251 * Destructor.
252 */
253 virtual ~Resource();
254
255 /**
256 * Write configuration information for this resource to a configuration
257 * file. If you override this method, remember to call Resource::writeConfig
258 * or Terrible Things(TM) will happen.
259 * @param config Configuration to write persistence information to.
260 */
261 virtual void writeConfig( KConfig* config );
262
263 /**
264 * Open this resource, if it not already open. Increase the open
265 * count of this object, and open the resource by calling @ref doOpen().
266 * This method may block while another thread is concurrently opening
267 * or closing the resource.
268 *
269 * Returns true if the resource was already opened or if it was opened
270 * successfully; returns false if the resource was not opened successfully.
271 */
272 bool open();
273
274 /**
275 * Decrease the open count of this object, and if the count reaches
276 * zero, close this resource by calling @ref doClose().
277 * This method may block while another thread is concurrently closing
278 * or opening the resource.
279 */
280 void close();
281
282 /**
283 * Returns whether the resource is open or not.
284 */
285 bool isOpen() const;
286
287 /**
288 * Returns a unique identifier. The identifier is unique for this resource.
289 * It is created when the resource is first created, and it is retained
290 * in the resource family configuration file for this resource.
291 * @return This resource's identifier
292 */
293 QString identifier() const;
294
295 /**
296 * Returns the type of this resource.
297 */
298 QString type() const;
299
300 /**
301 * Mark the resource as read-only. You can override this method,
302 * but also remember to call Resource::setReadOnly().
303 */
304 virtual void setReadOnly( bool value );
305
306 /**
307 * Returns, if the resource is read-only.
308 */
309 virtual bool readOnly() const;
310
311 /**
312 * Set the name of resource.You can override this method,
313 * but also remember to call Resource::setResourceName().
314 */
315 virtual void setResourceName( const QString &name );
316
317 /**
318 * Returns the name of resource.
319 */
320 virtual QString resourceName() const;
321
322 /**
323 Sets, if the resource is active.
324 */
325 void setActive( bool active );
326
327 /**
328 Return true, if the resource is active.
329 */
330 bool isActive() const;
331
332 friend class Factory;
333 friend class ManagerImpl;
334
335 /**
336 Print resource information as debug output.
337 */
338 virtual void dump() const;
339
340 protected:
341 /**
342 * Open this resource. When called, the resource must be in
343 * a closed state.
344 *
345 * Returns true if the resource was opened successfully;
346 * returns false if the resource was not opened successfully.
347 *
348 * The result of this call can be accessed later by @ref isOpen()
349 */
350 virtual bool doOpen() { return true; }
351
352 /**
353 * Close this resource. Pre-condition: resource is open.
354 * Post-condition: resource is closed.
355 */
356 virtual void doClose() {}
357
358 void setIdentifier( const QString& identifier );
359 void setType( const QString& type );
360
361 private:
362 class ResourcePrivate;
363 ResourcePrivate *d;
364};
365
366//US class PluginFactoryBase : public KLibFactory
367class PluginFactoryBase
368{
369 public:
370 virtual Resource *resource( const KConfig *config ) = 0;
371
372 virtual ConfigWidget *configWidget( QWidget *parent ) = 0;
373
374 protected:
375 virtual QObject* createObject( QObject*, const char*, const char*,
376 const QStringList & )
377 {
378 return 0;
379 }
380};
381
382template<class TR,class TC>
383class PluginFactory : public PluginFactoryBase
384{
385 public:
386 Resource *resource( const KConfig *config )
387 {
388 return new TR( config );
389 }
390
391 ConfigWidget *configWidget( QWidget *parent )
392 {
393 return new TC( parent );
394 }
395};
396
397
398
399}
400
401#endif
diff --git a/microkde/kresources/resourceselectdialog.h b/microkde/kresources/resourceselectdialog.h
new file mode 100644
index 0000000..fef689d
--- a/dev/null
+++ b/microkde/kresources/resourceselectdialog.h
@@ -0,0 +1,12 @@
1#ifndef MICRO_KRES_RESOURCESELECTDIALOG_H
2#define MICRO_KRES_RESOURCESELECTDIALOG_H
3
4namespace KRES {
5
6class ResourceSelectDialog
7{
8};
9
10}
11
12#endif
diff --git a/microkde/kresources/selectdialog.cpp b/microkde/kresources/selectdialog.cpp
new file mode 100644
index 0000000..fba8648
--- a/dev/null
+++ b/microkde/kresources/selectdialog.cpp
@@ -0,0 +1,154 @@
1/*
2 This file is part of libkresources.
3
4 Copyright (c) 2002 Tobias Koenig <tokoe@kde.org>
5 Copyright (c) 2002 Jan-Pascal van Best <janpascal@vanbest.org>
6 Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org>
7
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Library General Public
10 License as published by the Free Software Foundation; either
11 version 2 of the License, or (at your option) any later version.
12
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Library General Public License for more details.
17
18 You should have received a copy of the GNU Library General Public License
19 along with this library; see the file COPYING.LIB. If not, write to
20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA.
22*/
23
24/*US
25#include <kbuttonbox.h>
26#include <klistbox.h>
27#include <klocale.h>
28#include <kmessagebox.h>
29
30*/
31#include <klocale.h>
32#include <kmessagebox.h>
33
34//US
35#include <kglobal.h>
36
37#include <qlistbox.h>
38#include <qlayout.h>
39#include <qgroupbox.h>
40
41#include "resource.h"
42
43#include "selectdialog.h"
44
45using namespace KRES;
46
47//US I am using KBaseDialog instead of KDialog
48//US : KDialog( parent, name, true )
49SelectDialog::SelectDialog( QPtrList<Resource> list, QWidget *parent,
50 const char *name )
51 : KDialogBase( parent, name, true, i18n( "Resource Selection" ), Help | Ok | Cancel,
52 Ok, true)
53
54{
55//US setCaption( i18n( "Resource Selection" ) );
56//US resize( 300, 200 );
57 resize( KMIN(KGlobal::getDesktopWidth(), 300), KMIN(KGlobal::getDesktopHeight(), 200) );
58
59//US
60 QFrame *main = plainPage();
61/*US
62 QVBoxLayout *layout = new QVBoxLayout( main );
63 mConfigPage = new KRES::ConfigPage( main );
64 layout->addWidget( mConfigPage );
65*/
66
67//US QVBoxLayout *mainLayout = new QVBoxLayout( this );
68 QVBoxLayout *mainLayout = new QVBoxLayout( main );
69 mainLayout->setMargin( marginHint() );
70
71//US QGroupBox *groupBox = new QGroupBox( 2, Qt::Horizontal, this );
72 QGroupBox *groupBox = new QGroupBox( 2, Qt::Horizontal, main );
73 groupBox->setTitle( i18n( "Resources" ) );
74
75//US mResourceId = new KListBox( groupBox );
76 mResourceId = new QListBox( groupBox );
77
78 mainLayout->addWidget( groupBox );
79
80 mainLayout->addSpacing( 40 );
81
82/*US
83 KButtonBox *buttonBox = new KButtonBox( this );
84
85 buttonBox->addStretch();
86 buttonBox->addButton( i18n( "&OK" ), this, SLOT( accept() ) );
87 buttonBox->addButton( i18n( "&Cancel" ), this, SLOT( reject() ) );
88 buttonBox->layout();
89
90 mainLayout->addWidget( buttonBox );
91*/
92 // setup listbox
93 uint counter = 0;
94 for ( uint i = 0; i < list.count(); ++i ) {
95 Resource *resource = list.at( i );
96 if ( resource && !resource->readOnly() ) {
97 mResourceMap.insert( counter, resource );
98 mResourceId->insertItem( resource->resourceName() );
99 counter++;
100 }
101 }
102
103 mResourceId->setCurrentItem( 0 );
104 connect( mResourceId, SIGNAL(returnPressed(QListBoxItem*)),
105 SLOT(accept()) );
106}
107
108Resource *SelectDialog::resource()
109{
110 if ( mResourceId->currentItem() != -1 )
111 return mResourceMap[ mResourceId->currentItem() ];
112 else
113 return 0;
114}
115
116Resource *SelectDialog::getResource( QPtrList<Resource> list, QWidget *parent )
117{
118 if ( list.count() == 0 ) {
119 KMessageBox::error( parent, i18n( "There is no resource available!" ) );
120 return 0;
121 }
122
123 if ( list.count() == 1 ) return list.first();
124
125 // the following lines will return a writeable resource if only _one_ writeable
126 // resource exists
127 Resource *found = 0;
128 Resource *it = list.first();
129 while ( it ) {
130 if ( !it->readOnly() ) {
131 if ( found ) {
132 found = 0;
133 break;
134 } else
135 found = it;
136 }
137 it = list.next();
138 }
139
140 if ( found )
141 return found;
142
143 SelectDialog dlg( list, parent);
144//US if ( dlg.exec() == KDialog::Accepted )
145 if ( dlg.exec() )
146 return dlg.resource();
147 else
148 return 0;
149}
150
151/*US
152#include "selectdialog.moc"
153*/
154
diff --git a/microkde/kresources/selectdialog.h b/microkde/kresources/selectdialog.h
new file mode 100644
index 0000000..7026212
--- a/dev/null
+++ b/microkde/kresources/selectdialog.h
@@ -0,0 +1,92 @@
1/*
2 This file is part of libkresources.
3
4 Copyright (c) 2002 Tobias Koenig <tokoe@kde.org>
5 Copyright (c) 2002 Jan-Pascal van Best <janpascal@vanbest.org>
6 Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org>
7
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Library General Public
10 License as published by the Free Software Foundation; either
11 version 2 of the License, or (at your option) any later version.
12
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Library General Public License for more details.
17
18 You should have received a copy of the GNU Library General Public License
19 along with this library; see the file COPYING.LIB. If not, write to
20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA.
22*/
23
24#ifndef KRESOURCES_SELECTDIALOG_H
25#define KRESOURCES_SELECTDIALOG_H
26
27#include <qobject.h>
28#include <qptrlist.h>
29#include <qmap.h>
30
31#include <kdialogbase.h>
32
33//US class KListBox;
34class QListBox;
35
36namespace KRES {
37
38class Resource;
39
40/**
41 * Dialog for selecting a resource.
42 *
43 * Example:
44 *
45 * <pre>
46 * KABC::Resource *res = KABC::SelectDialog::getResource();
47 * if ( !( res ) ) {
48 * // no resource selected
49 * } else {
50 * // do something with resource
51 * }
52 * </pre>
53 */
54//US class SelectDialog : KDialog
55class SelectDialog : KDialogBase
56{
57 // Q_OBJECT
58 public:
59 /**
60 * Constructor.
61 * @param ab The address book you want to select the resource from
62 * @param parent The parent widget
63 * @param name The name of the dialog
64 */
65 SelectDialog( QPtrList<Resource> list, QWidget *parent = 0,
66 const char *name = 0);
67
68 // ~SelectDialog();
69
70 /**
71 * Return selected resource.
72 */
73 Resource *resource();
74
75 /**
76 * Open a dialog showing the available resources and return the resource the
77 * user has selected. Returns 0, if the dialog was canceled.
78 */
79 static Resource *getResource( QPtrList<Resource> list, QWidget *parent = 0 );
80
81 private:
82//US KListBox *mResourceId;
83 QListBox *mResourceId;
84
85 QMap<int, Resource*> mResourceMap;
86};
87
88
89
90}
91
92#endif
diff --git a/microkde/krestrictedline.h b/microkde/krestrictedline.h
new file mode 100644
index 0000000..200546c
--- a/dev/null
+++ b/microkde/krestrictedline.h
@@ -0,0 +1,13 @@
1#ifndef MINIKDE_KRESTRICTEDLINE_H
2#define MINIKDE_KRESTRICTEDLINE_H
3
4#include "klineedit.h"
5
6class KRestrictedLine : public KLineEdit
7{
8 public:
9 KRestrictedLine( QWidget *parent, const char *, const QString & ) :
10 KLineEdit( parent ) {}
11};
12
13#endif
diff --git a/microkde/krun.cpp b/microkde/krun.cpp
new file mode 100644
index 0000000..a170add
--- a/dev/null
+++ b/microkde/krun.cpp
@@ -0,0 +1,6 @@
1#include "krun.h"
2
3bool KRun::runCommand(const QString &, const QString &, const QString &)
4{
5 return false;
6}
diff --git a/microkde/krun.h b/microkde/krun.h
new file mode 100644
index 0000000..1b63cb7
--- a/dev/null
+++ b/microkde/krun.h
@@ -0,0 +1,13 @@
1#ifndef MINIKDE_KRUN_H
2#define MINIKDE_KRUN_H
3
4#include <qstring.h>
5
6class KRun
7{
8 public:
9 static bool runCommand(const QString &a, const QString &b=QString::null,
10 const QString &c=QString::null);
11};
12
13#endif
diff --git a/microkde/ksimpleconfig.h b/microkde/ksimpleconfig.h
new file mode 100644
index 0000000..1efd982
--- a/dev/null
+++ b/microkde/ksimpleconfig.h
@@ -0,0 +1,12 @@
1#ifndef MINIKDE_KSIMPLECONFIG_H
2#define MINIKDE_KSIMPLECONFIG_H
3
4#include "kconfig.h"
5
6class KSimpleConfig : public KConfig
7{
8 public:
9 KSimpleConfig( const QString &file ) : KConfig( file ) {}
10};
11
12#endif
diff --git a/microkde/kstandarddirs_old.cpp b/microkde/kstandarddirs_old.cpp
new file mode 100644
index 0000000..ac2c085
--- a/dev/null
+++ b/microkde/kstandarddirs_old.cpp
@@ -0,0 +1,151 @@
1#include "kdebug.h"
2#include "kurl.h"
3
4#include "kstandarddirs.h"
5#ifdef DESKTOP_VERSION
6#include <qregexp.h>
7#include <qmessagebox.h>
8
9#endif
10
11
12#include <qfile.h>
13#include <qdir.h>
14
15QString KStandardDirs::mAppDir = QString::null;
16
17QString locate( const char *type, const QString& filename )
18{
19/*US why do we put all files into one directory. It is quit complicated.
20why not staying with the original directorystructure ?
21
22
23 QString escapedFilename = filename;
24 escapedFilename.replace( QRegExp( "/" ), "_" );
25
26 QString path = KStandardDirs::appDir() + type + "_" + escapedFilename;
27
28 kdDebug() << "locate: '" << path << "'" << endl;
29 qDebug("locate: %s" , path.latin1());
30 return path;
31*/
32//US so my proposal is this:
33
34// QString escapedFilename = filename;
35// escapedFilename.replace( QRegExp( "/" ), "_" );
36
37#ifdef _WIN32_
38 QString path = QDir::convertSeparators(KStandardDirs::appDir() + type + "/" + filename);
39#else
40 QString path = KStandardDirs::appDir() + type + "/" + filename;
41#endif
42
43 //US Create the containing dir if needed
44 KURL pathurl;
45 pathurl.setPath(path);
46 QString dir=pathurl.directory();
47 //QMessageBox::information( 0,"path", path, 1 );
48#ifdef _WIN32_
49 KStandardDirs::makeDir(path);
50#else
51 KStandardDirs::makeDir(dir);
52#endif
53
54 kdDebug() << "locate: '" << path << "'" << endl;
55 qDebug("locate: %s" , path.latin1());
56 return path;
57
58
59}
60
61QString locateLocal( const char *type, const QString& filename )
62{
63 return locate( type, filename );
64}
65
66QStringList KStandardDirs::findAllResources( const QString &, const QString &, bool, bool)
67{
68 return QStringList();
69}
70
71QString KStandardDirs::findResourceDir( const QString &, const QString & )
72{
73 return QString::null;
74}
75
76void KStandardDirs::setAppDir( const QString &appDir )
77{
78 mAppDir = appDir;
79
80 if ( mAppDir.right( 1 ) != "/" ) mAppDir += "/";
81}
82
83bool KStandardDirs::makeDir(const QString& dir, int mode)
84{
85 QDir dirObj;
86
87
88 // we want an absolute path
89#ifndef _WIN32_
90 if (dir.at(0) != '/')
91 return false;
92#endif
93
94
95
96 QString target = dir;
97 uint len = target.length();
98#ifndef _WIN32_
99 // append trailing slash if missing
100 if (dir.at(len - 1) != '/')
101 target += '/';
102#endif
103
104 QString base("");
105 uint i = 1;
106
107 while( i < len )
108 {
109//US struct stat st;
110#ifndef _WIN32_
111 int pos = target.find('/', i);
112#else
113 int pos = target.find('\\', i);
114#endif
115 if ( pos < 0 )
116 return true;
117 base += target.mid(i - 1, pos - i + 1);
118 //QMessageBox::information( 0,"cap111", base, 1 );
119/*US
120 QCString baseEncoded = QFile::encodeName(base);
121 // bail out if we encountered a problem
122 if (stat(baseEncoded, &st) != 0)
123 {
124 // Directory does not exist....
125 // Or maybe a dangling symlink ?
126 if (lstat(baseEncoded, &st) == 0)
127 (void)unlink(baseEncoded); // try removing
128
129
130 if ( mkdir(baseEncoded, (mode_t) mode) != 0) {
131 perror("trying to create local folder");
132 return false; // Couldn't create it :-(
133 }
134 }
135*/
136
137 if (dirObj.exists(base) == false)
138 {
139 qDebug("KStandardDirs::makeDir try to create : %s" , base.latin1());
140 if (dirObj.mkdir(base) != true)
141 {
142 qDebug("KStandardDirs::makeDir could not create: %s" , base.latin1());
143 return false;
144 }
145 }
146
147 i = pos + 1;
148 }
149 return true;
150}
151
diff --git a/microkde/kstandarddirs_old.h b/microkde/kstandarddirs_old.h
new file mode 100644
index 0000000..87f8d69
--- a/dev/null
+++ b/microkde/kstandarddirs_old.h
@@ -0,0 +1,35 @@
1#ifndef MINIKDE_KSTANDARDDIRS_H
2#define MINIKDE_KSTANDARDDIRS_H
3
4#include <qstring.h>
5#include <qstringlist.h>
6
7QString locate( const char *type, const QString& filename );
8QString locateLocal( const char *type, const QString& filename );
9
10class KStandardDirs
11{
12 public:
13 QStringList findAllResources( const QString &, const QString &, bool, bool);
14 QString findResourceDir( const QString &, const QString & );
15
16 static void setAppDir( const QString & );
17 static QString appDir() { return mAppDir; }
18
19 /**
20 * Recursively creates still-missing directories in the given path.
21 *
22 * The resulting permissions will depend on the current umask setting.
23 * permission = mode & ~umask.
24 *
25 * @param dir Absolute path of the directory to be made.
26 * @param mode Directory permissions.
27 * @return true if successful, false otherwise
28 */
29 static bool makeDir(const QString& dir, int mode = 0755);
30
31 private:
32 static QString mAppDir;
33};
34
35#endif
diff --git a/microkde/kstaticdeleter.h b/microkde/kstaticdeleter.h
new file mode 100644
index 0000000..190f3e4
--- a/dev/null
+++ b/microkde/kstaticdeleter.h
@@ -0,0 +1,35 @@
1/*
2 * This file is part of the KDE Libraries
3 * Copyright (C) 2000 Stephan Kulow <coolo@kde.org>
4 * 2001 KDE Team
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public License
17 * along with this library; see the file COPYING.LIB. If not, write to
18 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
20 *
21 */
22
23#ifndef _KSTATIC_DELETER_H_
24#define _KSTATIC_DELETER_H_
25
26template<class type>
27class KStaticDeleter
28{
29 public:
30 KStaticDeleter() {};
31 type *setObject( type *obj, bool isArray = false) { return obj; }
32 virtual ~KStaticDeleter() {};
33};
34
35#endif
diff --git a/microkde/ksystemtray.cpp b/microkde/ksystemtray.cpp
new file mode 100644
index 0000000..4f81d02
--- a/dev/null
+++ b/microkde/ksystemtray.cpp
@@ -0,0 +1,11 @@
1#include "ksystemtray.h"
2
3void KSystemTray::mousePressEvent( QMouseEvent *)
4{
5 ; //qDebug("hallo");
6}
7
8KSystemTray::KSystemTray( QWidget *parent ) : QLabel( parent )
9{
10
11}
diff --git a/microkde/ksystemtray.h b/microkde/ksystemtray.h
new file mode 100644
index 0000000..f3e4f6a
--- a/dev/null
+++ b/microkde/ksystemtray.h
@@ -0,0 +1,14 @@
1#ifndef MICROKDE_KSYSTEMTRAY_H
2#define MICROKDE_KSYSTEMTRAY_H
3
4#include <qlabel.h>
5
6class KSystemTray : public QLabel
7{
8 Q_OBJECT
9 public:
10 KSystemTray( QWidget *parent = 0 );
11 void mousePressEvent( QMouseEvent *);
12};
13
14#endif
diff --git a/microkde/ktempfile.cpp b/microkde/ktempfile.cpp
new file mode 100644
index 0000000..b9166bd
--- a/dev/null
+++ b/microkde/ktempfile.cpp
@@ -0,0 +1,25 @@
1#include <qtextstream.h>
2
3#include "ktempfile.h"
4
5KTempFile::KTempFile()
6{
7}
8
9KTempFile::KTempFile( const QString &filename, const QString &extension )
10{
11}
12
13void KTempFile::setAutoDelete( bool )
14{
15}
16
17QString KTempFile::name()
18{
19 return QString::null;
20}
21
22QTextStream *KTempFile::textStream()
23{
24 return 0;
25}
diff --git a/microkde/ktempfile.h b/microkde/ktempfile.h
new file mode 100644
index 0000000..20dfa82
--- a/dev/null
+++ b/microkde/ktempfile.h
@@ -0,0 +1,20 @@
1#ifndef MINIKDE_KTEMPFILE_H
2#define MINIKDE_KTEMPFILE_H
3
4#include <qstring.h>
5
6class QTextStream;
7
8class KTempFile
9{
10 public:
11 KTempFile();
12 KTempFile( const QString &filename, const QString &extension );
13
14 void setAutoDelete( bool );
15 QString name();
16
17 QTextStream *textStream();
18};
19
20#endif
diff --git a/microkde/ktextedit.cpp b/microkde/ktextedit.cpp
new file mode 100644
index 0000000..4dd6875
--- a/dev/null
+++ b/microkde/ktextedit.cpp
@@ -0,0 +1,53 @@
1
2#include <ktextedit.h>
3#ifndef DESKTOP_VERSION
4#include <qpe/qpeapplication.h>
5#endif
6
7
8KTextEdit::KTextEdit ( QWidget *parent ) : QMultiLineEdit( parent )
9{
10 mAllowPopupMenu = false;
11 mMouseDown = false;
12 mIgnoreMark = false;
13#ifndef DESKTOP_VERSION
14 QPEApplication::setStylusOperation( this, QPEApplication::RightOnHold );
15#endif
16}
17
18void KTextEdit::mousePressEvent(QMouseEvent *e)
19{
20 if ( e->button() == LeftButton ) {
21 mAllowPopupMenu = true;
22 mYMousePos = mapToGlobal( (e->pos())).y();
23 mXMousePos = mapToGlobal( (e->pos())).x();
24 }
25 if ( e->button() == RightButton && !mAllowPopupMenu )
26 return;
27 if ( e->button() == LeftButton ) {
28 if ( hasMarkedText () )
29 mIgnoreMark = !mIgnoreMark;
30 if ( mIgnoreMark && hasMarkedText () ) {
31 mMouseDown = false;
32 return ;
33 }
34 }
35 QMultiLineEdit::mousePressEvent( e );
36}
37
38void KTextEdit::mouseReleaseEvent(QMouseEvent *e)
39{
40 QMultiLineEdit::mouseReleaseEvent(e);
41}
42
43void KTextEdit::mouseMoveEvent(QMouseEvent *e)
44{
45 int diff = mYMousePos - mapToGlobal( (e->pos())).y();
46 if ( diff < 0 ) diff = -diff;
47 int diff2 = mXMousePos - mapToGlobal( (e->pos())).x();
48 if ( diff2 < 0 ) diff2 = -diff2;
49 if ( diff+ diff2 > 20 )
50 mAllowPopupMenu = false;
51 QMultiLineEdit::mouseMoveEvent(e);
52}
53
diff --git a/microkde/ktextedit.h b/microkde/ktextedit.h
new file mode 100644
index 0000000..c912f3b
--- a/dev/null
+++ b/microkde/ktextedit.h
@@ -0,0 +1,22 @@
1#ifndef MICROKDE_KTEXTEDIT_H
2#define MICROKDE_KTEXTEDIT_H
3
4#include <qmultilineedit.h>
5
6class KTextEdit : public QMultiLineEdit
7{
8 public:
9 KTextEdit( QWidget *parent ) ;
10
11 private:
12 bool mAllowPopupMenu;
13 bool mMouseDown;
14 bool mIgnoreMark;
15 int mYMousePos;
16 int mXMousePos;
17 void mousePressEvent(QMouseEvent *e);
18 void mouseReleaseEvent(QMouseEvent *e);
19 void mouseMoveEvent(QMouseEvent *e);
20};
21
22#endif
diff --git a/microkde/kunload.h b/microkde/kunload.h
new file mode 100644
index 0000000..1c3d00f
--- a/dev/null
+++ b/microkde/kunload.h
@@ -0,0 +1,6 @@
1#ifndef MINIKDE_KUNLOAD_H
2#define MINIKDE_KUNLOAD_H
3
4#define _UNLOAD(p)
5
6#endif
diff --git a/microkde/kurl.cpp b/microkde/kurl.cpp
new file mode 100644
index 0000000..2574e25
--- a/dev/null
+++ b/microkde/kurl.cpp
@@ -0,0 +1,1942 @@
1/*
2 Copyright (C) 1999 Torben Weis <weis@kde.org>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA.
18*/
19
20#include "kurl.h"
21
22#ifndef KDE_QT_ONLY
23#include <kdebug.h>
24#include <kglobal.h>
25//US#include <kidna.h>
26#endif
27
28#include <stdio.h>
29#include <assert.h>
30#include <ctype.h>
31#include <stdlib.h>
32#ifdef _WIN32_
33
34#else
35#include <unistd.h>
36#endif
37#include <qurl.h>
38#include <qdir.h>
39#include <qstringlist.h>
40#include <qregexp.h>
41//US#include <qstylesheet.h>
42#include <qmap.h>
43#include <qtextcodec.h>
44
45static const QString fileProt = "file";
46
47static QTextCodec * codecForHint( int encoding_hint /* not 0 ! */ )
48{
49 return QTextCodec::codecForMib( encoding_hint );
50}
51
52static QString encode( const QString& segment, bool encode_slash, int encoding_hint )
53{
54 const char *encode_string;
55 if (encode_slash)
56 encode_string = "<>#@\"&%?={}|^~[]\'`\\:+/";
57 else
58 encode_string = "<>#@\"&%?={}|^~[]\'`\\:+";
59
60 QCString local;
61 if (encoding_hint==0)
62 local = segment.local8Bit();
63 else
64 {
65 QTextCodec * textCodec = codecForHint( encoding_hint );
66 if (!textCodec)
67 local = segment.local8Bit();
68 else
69 local = textCodec->fromUnicode( segment );
70 }
71
72 int old_length = local.length();
73
74 if ( !old_length )
75 return segment.isNull() ? QString::null : QString(""); // differenciate null and empty
76
77 // a worst case approximation
78 QChar *new_segment = new QChar[ old_length * 3 + 1 ];
79 int new_length = 0;
80
81 for ( int i = 0; i < old_length; i++ )
82 {
83 // 'unsave' and 'reserved' characters
84 // according to RFC 1738,
85 // 2.2. URL Character Encoding Issues (pp. 3-4)
86 // WABA: Added non-ascii
87 unsigned char character = local[i];
88 if ( (character <= 32) || (character >= 127) ||
89 strchr(encode_string, character) )
90 {
91 new_segment[ new_length++ ] = '%';
92
93 unsigned int c = character / 16;
94 c += (c > 9) ? ('A' - 10) : '0';
95 new_segment[ new_length++ ] = c;
96
97 c = character % 16;
98 c += (c > 9) ? ('A' - 10) : '0';
99 new_segment[ new_length++ ] = c;
100
101 }
102 else
103 new_segment[ new_length++ ] = local[i];
104 }
105
106 QString result = QString(new_segment, new_length);
107 delete [] new_segment;
108 return result;
109}
110
111static QString encodeHost( const QString& segment, bool encode_slash, int encoding_hint )
112{
113 // Hostnames are encoded differently
114 // we use the IDNA transformation instead
115
116 // Note: when merging qt-addon, use QResolver::domainToAscii here
117#ifndef KDE_QT_ONLY
118 Q_UNUSED( encode_slash );
119 Q_UNUSED( encoding_hint );
120 return KIDNA::toAscii(segment);
121#else
122 return encode(segment, encode_slash, encoding_hint);
123#endif
124}
125
126static int hex2int( unsigned int _char )
127{
128 if ( _char >= 'A' && _char <='F')
129 return _char - 'A' + 10;
130 if ( _char >= 'a' && _char <='f')
131 return _char - 'a' + 10;
132 if ( _char >= '0' && _char <='9')
133 return _char - '0';
134 return -1;
135}
136
137// WABA: The result of lazy_encode isn't usable for a URL which
138// needs to satisfies RFC requirements. However, the following
139// operation will make it usable again:
140// encode(decode(...))
141//
142// As a result one can see that url.prettyURL() does not result in
143// a RFC compliant URL but that the following sequence does:
144// KURL(url.prettyURL()).url()
145
146
147static QString lazy_encode( const QString& segment )
148{
149 int old_length = segment.length();
150
151 if ( !old_length )
152 return QString::null;
153
154 // a worst case approximation
155 QChar *new_segment = new QChar[ old_length * 3 + 1 ];
156 int new_length = 0;
157
158 for ( int i = 0; i < old_length; i++ )
159 {
160 unsigned int character = segment[i].unicode(); // Don't use latin1()
161 // It returns 0 for non-latin1 values
162 // Small set of really ambiguous chars
163 if ((character < 32) || // Low ASCII
164 ((character == '%') && // The escape character itself
165 (i+2 < old_length) && // But only if part of a valid escape sequence!
166 (hex2int(segment[i+1].unicode())!= -1) &&
167 (hex2int(segment[i+2].unicode())!= -1)) ||
168 (character == '?') || // Start of query delimiter
169 (character == '@') || // Username delimiter
170 (character == '#') || // Start of reference delimiter
171 ((character == 32) && (i+1 == old_length))) // A trailing space
172 {
173 new_segment[ new_length++ ] = '%';
174
175 unsigned int c = character / 16;
176 c += (c > 9) ? ('A' - 10) : '0';
177 new_segment[ new_length++ ] = c;
178
179 c = character % 16;
180 c += (c > 9) ? ('A' - 10) : '0';
181 new_segment[ new_length++ ] = c;
182 }
183 else
184 new_segment[ new_length++ ] = segment[i];
185 }
186
187 QString result = QString(new_segment, new_length);
188 delete [] new_segment;
189 return result;
190}
191
192static void decode( const QString& segment, QString &decoded, QString &encoded, int encoding_hint=0, bool updateDecoded = true )
193{
194 decoded = QString::null;
195 encoded = segment;
196
197 int old_length = segment.length();
198 if ( !old_length )
199 return;
200
201 QTextCodec *textCodec = 0;
202 if (encoding_hint)
203 textCodec = codecForHint( encoding_hint );
204
205 if (!textCodec)
206 textCodec = QTextCodec::codecForLocale();
207
208 QCString csegment = textCodec->fromUnicode(segment);
209 // Check if everything went ok
210 if (textCodec->toUnicode(csegment) != segment)
211 {
212 // Uh oh
213 textCodec = codecForHint( 106 ); // Fall back to utf-8
214 csegment = textCodec->fromUnicode(segment);
215 }
216 old_length = csegment.length();
217
218 int new_length = 0;
219 int new_length2 = 0;
220
221 // make a copy of the old one
222 char *new_segment = new char[ old_length + 1 ];
223 QChar *new_usegment = new QChar[ old_length * 3 + 1 ];
224
225 int i = 0;
226 while( i < old_length )
227 {
228 bool bReencode = false;
229 unsigned char character = csegment[ i++ ];
230 if ((character <= ' ') || (character > 127))
231 bReencode = true;
232
233 new_usegment [ new_length2++ ] = character;
234 if (character == '%' )
235 {
236 int a = i+1 < old_length ? hex2int( csegment[i] ) : -1;
237 int b = i+1 < old_length ? hex2int( csegment[i+1] ) : -1;
238 if ((a == -1) || (b == -1)) // Only replace if sequence is valid
239 {
240 // Contains stray %, make sure to re-encode!
241 bReencode = true;
242 }
243 else
244 {
245 // Valid %xx sequence
246 character = a * 16 + b; // Replace with value of %dd
247 if (!character && updateDecoded)
248 break; // Stop at %00
249
250 new_usegment [ new_length2++ ] = (unsigned char) csegment[i++];
251 new_usegment [ new_length2++ ] = (unsigned char) csegment[i++];
252 }
253 }
254 if (bReencode)
255 {
256 new_length2--;
257 new_usegment [ new_length2++ ] = '%';
258
259 unsigned int c = character / 16;
260 c += (c > 9) ? ('A' - 10) : '0';
261 new_usegment[ new_length2++ ] = c;
262
263 c = character % 16;
264 c += (c > 9) ? ('A' - 10) : '0';
265 new_usegment[ new_length2++ ] = c;
266 }
267
268 new_segment [ new_length++ ] = character;
269 }
270 new_segment [ new_length ] = 0;
271
272 encoded = QString( new_usegment, new_length2);
273
274 // Encoding specified
275 if (updateDecoded)
276 {
277 QByteArray array;
278 array.setRawData(new_segment, new_length);
279 decoded = textCodec->toUnicode( array, new_length );
280 array.resetRawData(new_segment, new_length);
281 QCString validate = textCodec->fromUnicode(decoded);
282
283 if (strcmp(validate.data(), new_segment) != 0)
284 {
285 decoded = QString::fromLocal8Bit(new_segment, new_length);
286 }
287 }
288
289 delete [] new_segment;
290 delete [] new_usegment;
291}
292
293static QString decode(const QString &segment, int encoding_hint = 0)
294{
295 QString result;
296 QString tmp;
297 decode(segment, result, tmp, encoding_hint);
298 return result;
299}
300
301static QString cleanpath(const QString &path, bool cleanDirSeparator=true)
302{
303 if (path.isEmpty()) return QString::null;
304 int len = path.length();
305 bool slash = (len && path[len-1] == '/') ||
306 (len > 1 && path[len-2] == '/' && path[len-1] == '.');
307
308 // The following code cleans up directory path much like
309 // QDir::cleanDirPath() except it can be made to ignore multiple
310 // directory separators by setting the flag to false. That fixes
311 // bug# 15044, mail.altavista.com and other similar brain-dead server
312 // implementations that do not follow what has been specified in
313 // RFC 2396!! (dA)
314 QString result;
315 int cdUp, orig_pos, pos;
316
317 cdUp = 0;
318 pos = orig_pos = len;
319 while ( pos && (pos = path.findRev('/',--pos)) != -1 )
320 {
321 len = orig_pos - pos - 1;
322 if ( len == 2 && path[pos+1] == '.' && path[pos+2] == '.' )
323 cdUp++;
324 else
325 {
326 // Ignore any occurances of '.'
327 // This includes entries that simply do not make sense like /..../
328 if ( (len || !cleanDirSeparator) &&
329 (len != 1 || path[pos+1] != '.' ) )
330 {
331 if ( !cdUp )
332 result.prepend(path.mid(pos, len+1));
333 else
334 cdUp--;
335 }
336 }
337 orig_pos = pos;
338 }
339
340 if ( result.isEmpty() )
341 result = "/";
342 else if ( slash && result.at(result.length()-1) != '/' )
343 result.append('/');
344
345 return result;
346}
347
348bool KURL::isRelativeURL(const QString &_url)
349{
350 int len = _url.length();
351 if (!len) return true; // Very short relative URL.
352 const QChar *str = _url.unicode();
353
354 // Absolute URL must start with alpha-character
355 if (!isalpha(str[0].latin1()))
356 return true; // Relative URL
357
358 for(int i = 1; i < len; i++)
359 {
360 char c = str[i].latin1(); // Note: non-latin1 chars return 0!
361 if (c == ':')
362 return false; // Absolute URL
363
364 // Protocol part may only contain alpha, digit, + or -
365 if (!isalpha(c) && !isdigit(c) && (c != '+') && (c != '-'))
366 return true; // Relative URL
367 }
368 // URL did not contain ':'
369 return true; // Relative URL
370}
371
372KURL::List::List(const KURL &url)
373{
374 append( url );
375}
376
377KURL::List::List(const QStringList &list)
378{
379 for (QStringList::ConstIterator it = list.begin();
380 it != list.end();
381 it++)
382 {
383 append( KURL(*it) );
384 }
385}
386
387QStringList KURL::List::toStringList() const
388{
389 QStringList lst;
390 for( KURL::List::ConstIterator it = begin();
391 it != end();
392 it++)
393 {
394 lst.append( (*it).url() );
395 }
396 return lst;
397}
398
399
400KURL::KURL()
401{
402 reset();
403}
404
405KURL::~KURL()
406{
407}
408
409
410KURL::KURL( const QString &url, int encoding_hint )
411{
412 reset();
413 parse( url, encoding_hint );
414}
415
416KURL::KURL( const char * url, int encoding_hint )
417{
418 reset();
419 parse( QString::fromLatin1(url), encoding_hint );
420}
421
422KURL::KURL( const QCString& url, int encoding_hint )
423{
424 reset();
425 parse( QString::fromLatin1(url), encoding_hint );
426}
427
428KURL::KURL( const KURL& _u )
429{
430 *this = _u;
431}
432
433QDataStream & operator<< (QDataStream & s, const KURL & a)
434{
435 QString QueryForWire=a.m_strQuery_encoded;
436 if (!a.m_strQuery_encoded.isNull())
437 QueryForWire.prepend("?");
438
439 s << a.m_strProtocol << a.m_strUser << a.m_strPass << a.m_strHost
440 << a.m_strPath << a.m_strPath_encoded << QueryForWire << a.m_strRef_encoded
441 << Q_INT8(a.m_bIsMalformed ? 1 : 0) << a.m_iPort;
442 return s;
443}
444
445QDataStream & operator>> (QDataStream & s, KURL & a)
446{
447 Q_INT8 malf;
448 QString QueryFromWire;
449 s >> a.m_strProtocol >> a.m_strUser >> a.m_strPass >> a.m_strHost
450 >> a.m_strPath >> a.m_strPath_encoded >> QueryFromWire >> a.m_strRef_encoded
451 >> malf >> a.m_iPort;
452 a.m_bIsMalformed = (malf != 0);
453
454 if ( QueryFromWire.isEmpty() )
455 a.m_strQuery_encoded = QString::null;
456 else
457 a.m_strQuery_encoded = QueryFromWire.mid(1);
458
459 return s;
460}
461
462#ifndef QT_NO_NETWORKPROTOCOL
463KURL::KURL( const QUrl &u )
464{
465 *this = u;
466}
467#endif
468
469KURL::KURL( const KURL& _u, const QString& _rel_url, int encoding_hint )
470{
471 // WORKAROUND THE RFC 1606 LOOPHOLE THAT ALLOWS
472 // http:/index.html AS A VALID SYNTAX FOR RELATIVE
473 // URLS. ( RFC 2396 section 5.2 item # 3 )
474 QString rUrl = _rel_url;
475 int len = _u.m_strProtocol.length();
476 if ( !_u.m_strHost.isEmpty() && !rUrl.isEmpty() &&
477 rUrl.find( _u.m_strProtocol, 0, false ) == 0 &&
478 rUrl[len] == ':' && (rUrl[len+1] != '/' ||
479 (rUrl[len+1] == '/' && rUrl[len+2] != '/')) )
480 {
481 rUrl.remove( 0, rUrl.find( ':' ) + 1 );
482 }
483
484 if ( rUrl.isEmpty() )
485 {
486 *this = _u;
487 }
488 else if ( rUrl[0] == '#' )
489 {
490 *this = _u;
491 QString ref = decode(rUrl.mid(1), encoding_hint);
492 if ( ref.isNull() )
493 ref = ""; // we know there was an (empty) html ref, we saw the '#'
494 setHTMLRef( ref );
495 }
496 else if ( isRelativeURL( rUrl) )
497 {
498 *this = _u;
499 m_strQuery_encoded = QString::null;
500 m_strRef_encoded = QString::null;
501 if ( rUrl[0] == '/')
502 {
503 if ((rUrl.length() > 1) && (rUrl[1] == '/'))
504 {
505 m_strHost = QString::null;
506 }
507 m_strPath = QString::null;
508 m_strPath_encoded = QString::null;
509 }
510 else if ( rUrl[0] != '?' )
511 {
512 int pos = m_strPath.findRev( '/' );
513 if (pos >= 0)
514 m_strPath.truncate(pos);
515 m_strPath += '/';
516 if (!m_strPath_encoded.isEmpty())
517 {
518 pos = m_strPath_encoded.findRev( '/' );
519 if (pos >= 0)
520 m_strPath_encoded.truncate(pos);
521 m_strPath_encoded += '/';
522 }
523 }
524 else
525 {
526 if ( m_strPath.isEmpty() )
527 m_strPath = '/';
528 }
529 KURL tmp( url() + rUrl, encoding_hint);
530 *this = tmp;
531 cleanPath(false);
532 }
533 else
534 {
535 KURL tmp( rUrl, encoding_hint);
536 *this = tmp;
537 // Preserve userinfo if applicable.
538 if (!_u.m_strUser.isEmpty() && m_strUser.isEmpty() && (_u.m_strHost == m_strHost) && (_u.m_strProtocol == m_strProtocol))
539 {
540 m_strUser = _u.m_strUser;
541 m_strPass = _u.m_strPass;
542 }
543 }
544}
545
546void KURL::reset()
547{
548 m_strProtocol = QString::null;
549 m_strUser = QString::null;
550 m_strPass = QString::null;
551 m_strHost = QString::null;
552 m_strPath = QString::null;
553 m_strPath_encoded = QString::null;
554 m_strQuery_encoded = QString::null;
555 m_strRef_encoded = QString::null;
556 m_bIsMalformed = true;
557 m_iPort = 0;
558}
559
560bool KURL::isEmpty() const
561{
562 return (m_strPath.isEmpty() && m_strProtocol.isEmpty());
563}
564
565void KURL::parse( const QString& _url, int encoding_hint )
566{
567 //kdDebug(126) << "parse " << _url << endl;
568 // Return immediately whenever the given url
569 // is empty or null.
570 if ( _url.isEmpty() )
571 {
572 m_strProtocol = _url;
573 return;
574 }
575
576 QString port;
577 bool badHostName = false;
578 int start = 0;
579 uint len = _url.length();
580 const QChar* buf = _url.unicode();
581 const QChar* orig = buf;
582
583 QChar delim;
584 QString tmp;
585
586 uint pos = 0;
587
588 // Node 1: Accept alpha or slash
589 QChar x = buf[pos++];
590 if ( x == '/' )
591 goto Node9;
592 if ( !isalpha( (int)x ) )
593 goto NodeErr;
594
595 // Node 2: Accept any amount of (alpha|digit|'+'|'-')
596 // '.' is not currently accepted, because current KURL may be confused.
597 // Proceed with :// :/ or :
598 while( pos < len && (isalpha((int)buf[pos]) || isdigit((int)buf[pos]) ||
599 buf[pos] == '+' || buf[pos] == '-')) pos++;
600
601 if ( pos+2 < len && buf[pos] == ':' && buf[pos+1] == '/' && buf[pos+2] == '/' )
602 {
603 m_strProtocol = QString( orig, pos ).lower();
604 pos += 3;
605 }
606 else if (pos+1 < len && buf[pos] == ':' ) // Need to always compare length()-1 otherwise KURL passes "http:" as legal!!
607 {
608 m_strProtocol = QString( orig, pos ).lower();
609 //kdDebug(126)<<"setting protocol to "<<m_strProtocol<<endl;
610 pos++;
611 start = pos;
612 goto Node9;
613 }
614 else
615 goto NodeErr;
616
617 //Node 3: We need at least one character here
618 if ( pos == len )
619 goto NodeErr;
620 start = pos;
621
622 // Node 4: Accept any amount of characters.
623 if (buf[pos] == '[') // An IPv6 host follows.
624 goto Node8;
625 // Terminate on / or @ or ? or # or " or ; or <
626 x = buf[pos];
627 while( (x != ':') && (x != '@') && (x != '/') && (x != '?') && (x != '#') )
628 {
629 if ((x == '\"') || (x == ';') || (x == '<'))
630 badHostName = true;
631 if (++pos == len)
632 break;
633 x = buf[pos];
634 }
635 if ( pos == len )
636 {
637 if (badHostName)
638 goto NodeErr;
639
640 setHost(decode(QString( buf + start, pos - start ), encoding_hint));
641 goto NodeOk;
642 }
643 if ( x == '@' )
644 {
645 m_strUser = decode(QString( buf + start, pos - start ), encoding_hint);
646 pos++;
647 goto Node7;
648 }
649 else if ( (x == '/') || (x == '?') || (x == '#'))
650 {
651 if (badHostName)
652 goto NodeErr;
653
654 setHost(decode(QString( buf + start, pos - start ), encoding_hint));
655 start = pos;
656 goto Node9;
657 }
658 else if ( x != ':' )
659 goto NodeErr;
660 m_strUser = decode(QString( buf + start, pos - start ), encoding_hint);
661 pos++;
662
663 // Node 5: We need at least one character
664 if ( pos == len )
665 goto NodeErr;
666 start = pos++;
667
668 // Node 6: Read everything until @, /, ? or #
669 while( (pos < len) &&
670 (buf[pos] != '@') &&
671 (buf[pos] != '/') &&
672 (buf[pos] != '?') &&
673 (buf[pos] != '#')) pos++;
674 // If we now have a '@' the ':' seperates user and password.
675 // Otherwise it seperates host and port.
676 if ( (pos == len) || (buf[pos] != '@') )
677 {
678 // Ok the : was used to separate host and port
679 if (badHostName)
680 goto NodeErr;
681 setHost(m_strUser);
682 m_strUser = QString::null;
683 QString tmp( buf + start, pos - start );
684 char *endptr;
685 m_iPort = (unsigned short int)strtol(tmp.ascii(), &endptr, 10);
686 if ((pos == len) && (strlen(endptr) == 0))
687 goto NodeOk;
688 // there is more after the digits
689 pos -= strlen(endptr);
690 start = pos++;
691 goto Node9;
692 }
693 m_strPass = decode(QString( buf + start, pos - start), encoding_hint);
694 pos++;
695
696 // Node 7: We need at least one character
697 Node7:
698 if ( pos == len )
699 goto NodeErr;
700
701 Node8:
702 if (buf[pos] == '[')
703 {
704 // IPv6 address
705 start = ++pos; // Skip '['
706
707 if (pos == len)
708 {
709 badHostName = true;
710 goto NodeErr;
711 }
712 // Node 8b: Read everything until ] or terminate
713 badHostName = false;
714 x = buf[pos];
715 while( (x != ']') )
716 {
717 if ((x == '\"') || (x == ';') || (x == '<'))
718 badHostName = true;
719 if (++pos == len)
720 {
721 badHostName = true;
722 break;
723 }
724 x = buf[pos];
725 }
726 if (badHostName)
727 goto NodeErr;
728 setHost(decode(QString( buf + start, pos - start ), encoding_hint));
729 if (pos < len) pos++; // Skip ']'
730 if (pos == len)
731 goto NodeOk;
732 }
733 else
734 {
735 // Non IPv6 address
736 start = pos;
737
738 // Node 8b: Read everything until / : or terminate
739 badHostName = false;
740 x = buf[pos];
741 while( (x != ':') && (x != '@') && (x != '/') && (x != '?') && (x != '#') )
742 {
743 if ((x == '\"') || (x == ';') || (x == '<'))
744 badHostName = true;
745 if (++pos == len)
746 break;
747 x = buf[pos];
748 }
749 if (badHostName)
750 goto NodeErr;
751 if ( pos == len )
752 {
753 setHost(decode(QString( buf + start, pos - start ), encoding_hint));
754 goto NodeOk;
755 }
756 setHost(decode(QString( buf + start, pos - start ), encoding_hint));
757 }
758 x = buf[pos];
759 if ( x == '/' )
760 {
761 start = pos++;
762 goto Node9;
763 }
764 else if ( x != ':' )
765 goto NodeErr;
766 pos++;
767
768 // Node 8a: Accept at least one digit
769 if ( pos == len )
770 goto NodeErr;
771 start = pos;
772 if ( !isdigit( buf[pos++] ) )
773 goto NodeErr;
774
775 // Node 8b: Accept any amount of digits
776 while( pos < len && isdigit( buf[pos] ) ) pos++;
777 port = QString( buf + start, pos - start );
778 m_iPort = port.toUShort();
779 if ( pos == len )
780 goto NodeOk;
781 start = pos++;
782
783 Node9: // parse path until query or reference reached
784
785 while( pos < len && buf[pos] != '#' && buf[pos]!='?' ) pos++;
786
787 tmp = QString( buf + start, pos - start );
788 //kdDebug(126)<<" setting encoded path&query to:"<<tmp<<endl;
789 setEncodedPath( tmp, encoding_hint );
790
791 if ( pos == len )
792 goto NodeOk;
793
794 //Node10: // parse query or reference depending on what comes first
795 delim = (buf[pos++]=='#'?'?':'#');
796
797 start = pos;
798
799 while(pos < len && buf[pos]!=delim ) pos++;
800
801 tmp = QString(buf + start, pos - start);
802 if (delim=='#')
803 setQuery(tmp, encoding_hint);
804 else
805 m_strRef_encoded = tmp;
806
807 if (pos == len)
808 goto NodeOk;
809
810 //Node11: // feed the rest into the remaining variable
811 tmp = QString( buf + pos + 1, len - pos - 1);
812 if (delim == '#')
813 m_strRef_encoded = tmp;
814 else
815 setQuery(tmp, encoding_hint);
816
817 NodeOk:
818 //kdDebug(126)<<"parsing finished. m_strProtocol="<<m_strProtocol<<" m_strHost="<<m_strHost<<" m_strPath="<<m_strPath<<endl;
819 m_bIsMalformed = false; // Valid URL
820
821 //kdDebug()<<"Prot="<<m_strProtocol<<"\nUser="<<m_strUser<<"\nPass="<<m_strPass<<"\nHost="<<m_strHost<<"\nPath="<<m_strPath<<"\nQuery="<<m_strQuery_encoded<<"\nRef="<<m_strRef_encoded<<"\nPort="<<m_iPort<<endl;
822 if (m_strProtocol.isEmpty())
823 {
824 m_strProtocol = fileProt;
825 }
826 return;
827
828 NodeErr:
829// kdDebug(126) << "KURL couldn't parse URL \"" << _url << "\"" << endl;
830 reset();
831 m_strProtocol = _url;
832}
833
834KURL& KURL::operator=( const QString& _url )
835{
836 reset();
837 parse( _url );
838
839 return *this;
840}
841
842KURL& KURL::operator=( const char * _url )
843{
844 reset();
845 parse( QString::fromLatin1(_url) );
846
847 return *this;
848}
849
850#ifndef QT_NO_NETWORKPROTOCOL
851KURL& KURL::operator=( const QUrl & u )
852{
853 m_strProtocol = u.protocol();
854 m_strUser = u.user();
855 m_strPass = u.password();
856 m_strHost = u.host();
857 m_strPath = u.path( FALSE );
858 m_strPath_encoded = QString::null;
859 m_strQuery_encoded = u.query();
860 m_strRef_encoded = u.ref();
861 m_bIsMalformed = !u.isValid();
862 m_iPort = u.port();
863
864 return *this;
865}
866#endif
867
868KURL& KURL::operator=( const KURL& _u )
869{
870 m_strProtocol = _u.m_strProtocol;
871 m_strUser = _u.m_strUser;
872 m_strPass = _u.m_strPass;
873 m_strHost = _u.m_strHost;
874 m_strPath = _u.m_strPath;
875 m_strPath_encoded = _u.m_strPath_encoded;
876 m_strQuery_encoded = _u.m_strQuery_encoded;
877 m_strRef_encoded = _u.m_strRef_encoded;
878 m_bIsMalformed = _u.m_bIsMalformed;
879 m_iPort = _u.m_iPort;
880
881 return *this;
882}
883
884bool KURL::operator==( const KURL& _u ) const
885{
886 if ( isMalformed() || _u.isMalformed() )
887 return false;
888
889 if ( m_strProtocol == _u.m_strProtocol &&
890 m_strUser == _u.m_strUser &&
891 m_strPass == _u.m_strPass &&
892 m_strHost == _u.m_strHost &&
893 m_strPath == _u.m_strPath &&
894 // The encoded path may be null, but the URLs are still equal (David)
895 ( m_strPath_encoded.isNull() || _u.m_strPath_encoded.isNull() ||
896 m_strPath_encoded == _u.m_strPath_encoded ) &&
897 m_strQuery_encoded == _u.m_strQuery_encoded &&
898 m_strRef_encoded == _u.m_strRef_encoded &&
899 m_iPort == _u.m_iPort )
900 {
901 return true;
902 }
903
904 return false;
905}
906
907bool KURL::operator==( const QString& _u ) const
908{
909 KURL u( _u );
910 return ( *this == u );
911}
912
913bool KURL::cmp( const KURL &u, bool ignore_trailing ) const
914{
915 return equals( u, ignore_trailing );
916}
917
918bool KURL::equals( const KURL &_u, bool ignore_trailing ) const
919{
920 if ( isMalformed() || _u.isMalformed() )
921 return false;
922
923 if ( ignore_trailing )
924 {
925 QString path1 = path(1);
926 QString path2 = _u.path(1);
927 if ( path1 != path2 )
928 return false;
929
930 if ( m_strProtocol == _u.m_strProtocol &&
931 m_strUser == _u.m_strUser &&
932 m_strPass == _u.m_strPass &&
933 m_strHost == _u.m_strHost &&
934 m_strQuery_encoded == _u.m_strQuery_encoded &&
935 m_strRef_encoded == _u.m_strRef_encoded &&
936 m_iPort == _u.m_iPort )
937 return true;
938
939 return false;
940 }
941
942 return ( *this == _u );
943}
944
945bool KURL::isParentOf( const KURL& _u ) const
946{
947 if ( isMalformed() || _u.isMalformed() )
948 return false;
949
950 if ( m_strProtocol == _u.m_strProtocol &&
951 m_strUser == _u.m_strUser &&
952 m_strPass == _u.m_strPass &&
953 m_strHost == _u.m_strHost &&
954 m_strQuery_encoded == _u.m_strQuery_encoded &&
955 m_strRef_encoded == _u.m_strRef_encoded &&
956 m_iPort == _u.m_iPort )
957 {
958 if ( path().isEmpty() || _u.path().isEmpty() )
959 return false; // can't work with implicit paths
960
961 QString p1( cleanpath( path() ) );
962 if ( p1.at(p1.length()-1) != '/' )
963 p1 += '/';
964 QString p2( cleanpath( _u.path() ) );
965 if ( p2.at(p2.length()-1) != '/' )
966 p2 += '/';
967
968 //kdDebug(126) << "p1=" << p1 << endl;
969 //kdDebug(126) << "p2=" << p2 << endl;
970 //kdDebug(126) << "p1.length()=" << p1.length() << endl;
971 //kdDebug(126) << "p2.left(!$)=" << p2.left( p1.length() ) << endl;
972 return p2.startsWith( p1 );
973 }
974 return false;
975}
976
977void KURL::setFileName( const QString& _txt )
978{
979 m_strRef_encoded = QString::null;
980 int i = 0;
981 while( _txt[i] == '/' ) ++i;
982 QString tmp;
983 if ( i )
984 tmp = _txt.mid( i );
985 else
986 tmp = _txt;
987
988 QString path = m_strPath_encoded.isEmpty() ? m_strPath : m_strPath_encoded;
989 if ( path.isEmpty() )
990 path = "/";
991 else
992 {
993 int lastSlash = path.findRev( '/' );
994 if ( lastSlash == -1)
995 {
996 // The first character is not a '/' ???
997 // This looks strange ...
998 path = "/";
999 }
1000 else if ( path.right(1) != "/" )
1001 path.truncate( lastSlash+1 ); // keep the "/"
1002 }
1003 if (m_strPath_encoded.isEmpty())
1004 {
1005 path += tmp;
1006 setPath( path );
1007 }
1008 else
1009 {
1010 path += encode_string(tmp);
1011 setEncodedPath( path );
1012 }
1013 cleanPath();
1014}
1015
1016void KURL::cleanPath( bool cleanDirSeparator ) // taken from the old KURL
1017{
1018 m_strPath = cleanpath(m_strPath, cleanDirSeparator);
1019 // WABA: Is this safe when "/../" is encoded with %?
1020 m_strPath_encoded = cleanpath(m_strPath_encoded, cleanDirSeparator);
1021}
1022
1023static QString trailingSlash( int _trailing, const QString &path )
1024{
1025 QString result = path;
1026
1027 if ( _trailing == 0 )
1028 return result;
1029 else if ( _trailing == 1 )
1030 {
1031 int len = result.length();
1032 if ( len == 0 )
1033 result = QString::null;
1034 else if ( result[ len - 1 ] != '/' )
1035 result += "/";
1036 return result;
1037 }
1038 else if ( _trailing == -1 )
1039 {
1040 if ( result == "/" )
1041 return result;
1042 int len = result.length();
1043 if ( len != 0 && result[ len - 1 ] == '/' )
1044 result.truncate( len - 1 );
1045 return result;
1046 }
1047 else {
1048 assert( 0 );
1049 return QString::null;
1050 }
1051}
1052
1053void KURL::adjustPath( int _trailing )
1054{
1055 if (!m_strPath_encoded.isEmpty())
1056 {
1057 m_strPath_encoded = trailingSlash( _trailing, m_strPath_encoded );
1058 }
1059 m_strPath = trailingSlash( _trailing, m_strPath );
1060}
1061
1062
1063QString KURL::encodedPathAndQuery( int _trailing, bool _no_empty_path, int encoding_hint ) const
1064{
1065 QString tmp;
1066 if (!m_strPath_encoded.isEmpty() && encoding_hint == 0)
1067 {
1068 tmp = trailingSlash( _trailing, m_strPath_encoded );
1069 }
1070 else
1071 {
1072 tmp = path( _trailing );
1073 if ( _no_empty_path && tmp.isEmpty() )
1074 tmp = "/";
1075 tmp = encode( tmp, false, encoding_hint );
1076 }
1077
1078 // TODO apply encoding_hint to the query
1079 if (!m_strQuery_encoded.isNull())
1080 tmp += '?' + m_strQuery_encoded;
1081 return tmp;
1082}
1083
1084void KURL::setEncodedPath( const QString& _txt, int encoding_hint )
1085{
1086 m_strPath_encoded = _txt;
1087
1088 decode( m_strPath_encoded, m_strPath, m_strPath_encoded, encoding_hint );
1089 // Throw away encoding for local files, makes file-operations faster.
1090 if (m_strProtocol == fileProt)
1091 m_strPath_encoded = QString::null;
1092}
1093
1094
1095void KURL::setEncodedPathAndQuery( const QString& _txt, int encoding_hint )
1096{
1097 int pos = _txt.find( '?' );
1098 if ( pos == -1 )
1099 {
1100 setEncodedPath(_txt, encoding_hint);
1101 m_strQuery_encoded = QString::null;
1102 }
1103 else
1104 {
1105 setEncodedPath(_txt.left( pos ), encoding_hint);
1106 setQuery(_txt.right(_txt.length() - pos - 1), encoding_hint);
1107 }
1108}
1109
1110QString KURL::path( int _trailing ) const
1111{
1112 return trailingSlash( _trailing, path() );
1113}
1114
1115bool KURL::isLocalFile() const
1116{
1117 if ( (m_strProtocol != fileProt ) || hasSubURL() )
1118 return false;
1119
1120 if (m_strHost.isEmpty() || (m_strHost == "localhost"))
1121 return true;
1122
1123 char hostname[ 256 ];
1124 hostname[ 0 ] = '\0';
1125#ifdef _WIN32_
1126 // pending LR fixme
1127 //hostname = "localhost";
1128#else
1129 if (!gethostname( hostname, 255 ))
1130 hostname[sizeof(hostname)-1] = '\0';
1131#endif
1132 for(char *p = hostname; *p; p++)
1133 *p = tolower(*p);
1134
1135 return (m_strHost == hostname);
1136}
1137
1138void KURL::setFileEncoding(const QString &encoding)
1139{
1140 if (!isLocalFile())
1141 return;
1142
1143 QString q = query();
1144
1145 if (!q.isEmpty() && (q[0] == '?'))
1146 q = q.mid(1);
1147
1148 QStringList args = QStringList::split('&', q);
1149 for(QStringList::Iterator it = args.begin();
1150 it != args.end();)
1151 {
1152 QString s = decode_string(*it);
1153 if (s.startsWith("charset="))
1154//US changed erase into remove ???
1155 it = args.remove(it);
1156 else
1157 ++it;
1158 }
1159 if (!encoding.isEmpty())
1160 args.append("charset="+encode_string(encoding));
1161
1162 if (args.isEmpty())
1163 setQuery(QString::null);
1164 else
1165 setQuery(args.join("&"));
1166}
1167
1168QString KURL::fileEncoding() const
1169{
1170 if (!isLocalFile())
1171 return QString::null;
1172
1173 QString q = query();
1174
1175 if (q.isEmpty())
1176 return QString::null;
1177
1178 if (q[0] == '?')
1179 q = q.mid(1);
1180
1181 QStringList args = QStringList::split('&', q);
1182 for(QStringList::ConstIterator it = args.begin();
1183 it != args.end();
1184 ++it)
1185 {
1186 QString s = decode_string(*it);
1187 if (s.startsWith("charset="))
1188 return s.mid(8);
1189 }
1190 return QString::null;
1191}
1192
1193bool KURL::hasSubURL() const
1194{
1195 if ( m_strProtocol.isEmpty() || m_bIsMalformed )
1196 return false;
1197 if (m_strRef_encoded.isEmpty())
1198 return false;
1199 if (m_strRef_encoded.startsWith("gzip:"))
1200 return true;
1201 if (m_strRef_encoded.startsWith("bzip:"))
1202 return true;
1203 if (m_strRef_encoded.startsWith("bzip2:"))
1204 return true;
1205 if (m_strRef_encoded.startsWith("tar:"))
1206 return true;
1207 if ( m_strProtocol == "error" ) // anything that starts with error: has suburls
1208 return true;
1209 return false;
1210}
1211
1212QString KURL::url( int _trailing, int encoding_hint ) const
1213{
1214 if( m_bIsMalformed )
1215 {
1216 // Return the whole url even when the url is
1217 // malformed. Under such conditions the url
1218 // is stored in m_strProtocol.
1219 return m_strProtocol;
1220 }
1221
1222 QString u = m_strProtocol;
1223 if (!u.isEmpty())
1224 u += ":";
1225
1226 if ( hasHost() )
1227 {
1228 u += "//";
1229 if ( hasUser() )
1230 {
1231 u += encode(m_strUser, true, encoding_hint);
1232 if ( hasPass() )
1233 {
1234 u += ":";
1235 u += encode(m_strPass, true, encoding_hint);
1236 }
1237 u += "@";
1238 }
1239 bool IPv6 = (m_strHost.find(':') != -1);
1240 if (IPv6)
1241 u += '[' + m_strHost + ']';
1242 else
1243 u += encodeHost(m_strHost, true, encoding_hint);
1244 if ( m_iPort != 0 ) {
1245 QString buffer;
1246 buffer.sprintf( ":%u", m_iPort );
1247 u += buffer;
1248 }
1249 }
1250
1251 u += encodedPathAndQuery( _trailing, false, encoding_hint );
1252
1253 if ( hasRef() )
1254 {
1255 u += "#";
1256 u += m_strRef_encoded;
1257 }
1258
1259 return u;
1260}
1261
1262QString KURL::prettyURL( int _trailing ) const
1263{
1264 if( m_bIsMalformed )
1265 {
1266 // Return the whole url even when the url is
1267 // malformed. Under such conditions the url
1268 // is stored in m_strProtocol.
1269 return m_strProtocol;
1270 }
1271
1272 QString u = m_strProtocol;
1273 if (!u.isEmpty())
1274 u += ":";
1275
1276 if ( hasHost() )
1277 {
1278 u += "//";
1279 if ( hasUser() )
1280 {
1281 u += lazy_encode(m_strUser);
1282 // Don't show password!
1283 u += "@";
1284 }
1285 bool IPv6 = (m_strHost.find(':') != -1);
1286 if (IPv6)
1287 {
1288 u += '[' + m_strHost + ']';
1289 }
1290 else
1291 {
1292 u += lazy_encode(m_strHost);
1293 }
1294 if ( m_iPort != 0 ) {
1295 QString buffer;
1296 buffer.sprintf( ":%u", m_iPort );
1297 u += buffer;
1298 }
1299 }
1300
1301 u += trailingSlash( _trailing, lazy_encode( m_strPath ) );
1302 if (!m_strQuery_encoded.isNull())
1303 u += '?' + m_strQuery_encoded;
1304
1305 if ( hasRef() )
1306 {
1307 u += "#";
1308 u += m_strRef_encoded;
1309 }
1310
1311 return u;
1312}
1313
1314QString KURL::prettyURL( int _trailing, AdjustementFlags _flags) const
1315{
1316 QString u = prettyURL(_trailing);
1317 if (_flags & StripFileProtocol && u.startsWith("file:"))
1318 u.remove(0, 5);
1319 return u;
1320}
1321
1322QString KURL::htmlURL() const
1323{
1324//US QStyleSheet::escape was not in my Qt distribution. Why ???
1325//US return QStyleSheet::escape(prettyURL());
1326 return prettyURL();
1327}
1328
1329KURL::List KURL::split( const KURL& _url )
1330{
1331 QString ref;
1332 KURL::List lst;
1333 KURL url = _url;
1334
1335 while(true)
1336 {
1337 KURL u = url;
1338 u.m_strRef_encoded = QString::null;
1339 lst.append(u);
1340 if (url.hasSubURL())
1341 {
1342 url = KURL(url.m_strRef_encoded);
1343 }
1344 else
1345 {
1346 ref = url.m_strRef_encoded;
1347 break;
1348 }
1349 }
1350
1351 // Set HTML ref in all URLs.
1352 KURL::List::Iterator it;
1353 for( it = lst.begin() ; it != lst.end(); ++it )
1354 {
1355 (*it).m_strRef_encoded = ref;
1356 }
1357
1358 return lst;
1359}
1360
1361KURL::List KURL::split( const QString& _url )
1362{
1363 return split(KURL(_url));
1364}
1365
1366KURL KURL::join( const KURL::List & lst )
1367{
1368 if (lst.isEmpty()) return KURL();
1369 KURL tmp;
1370
1371 KURL::List::ConstIterator first = lst.fromLast();
1372 for( KURL::List::ConstIterator it = first; it != lst.end(); --it )
1373 {
1374 KURL u(*it);
1375 if (it != first)
1376 {
1377 if (!u.m_strRef_encoded) u.m_strRef_encoded = tmp.url();
1378 else u.m_strRef_encoded += "#" + tmp.url(); // Support more than one suburl thingy
1379 }
1380 tmp = u;
1381 }
1382
1383 return tmp;
1384}
1385
1386QString KURL::fileName( bool _strip_trailing_slash ) const
1387{
1388 QString fname;
1389 if (hasSubURL()) { // If we have a suburl, then return the filename from there
1390 KURL::List list = KURL::split(*this);
1391 KURL::List::Iterator it = list.fromLast();
1392 return (*it).fileName(_strip_trailing_slash);
1393 }
1394 const QString &path = m_strPath;
1395
1396 int len = path.length();
1397 if ( len == 0 )
1398 return fname;
1399
1400 if ( _strip_trailing_slash )
1401 {
1402 while ( len >= 1 && path[ len - 1 ] == '/' )
1403 len--;
1404 }
1405 else if ( path[ len - 1 ] == '/' )
1406 return fname;
1407
1408 // Does the path only consist of '/' characters ?
1409 if ( len == 1 && path[ 0 ] == '/' )
1410 return fname;
1411
1412 // Skip last n slashes
1413 int n = 1;
1414 if (!m_strPath_encoded.isEmpty())
1415 {
1416 // This is hairy, we need the last unencoded slash.
1417 // Count in the encoded string how many encoded slashes follow the last
1418 // unencoded one.
1419 int i = m_strPath_encoded.findRev( '/', len - 1 );
1420 QString fileName_encoded = m_strPath_encoded.mid(i+1);
1421 n += fileName_encoded.contains("%2f", false);
1422 }
1423 int i = len;
1424 do {
1425 i = path.findRev( '/', i - 1 );
1426 }
1427 while (--n && (i > 0));
1428
1429 // If ( i == -1 ) => the first character is not a '/'
1430 // So it's some URL like file:blah.tgz, return the whole path
1431 if ( i == -1 ) {
1432 if ( len == (int)path.length() )
1433 fname = path;
1434 else
1435 // Might get here if _strip_trailing_slash is true
1436 fname = path.left( len );
1437 }
1438 else
1439 {
1440 fname = path.mid( i + 1, len - i - 1 ); // TO CHECK
1441 }
1442 return fname;
1443}
1444
1445void KURL::addPath( const QString& _txt )
1446{
1447 if (hasSubURL())
1448 {
1449 KURL::List lst = split( *this );
1450 KURL &u = lst.last();
1451 u.addPath(_txt);
1452 *this = join( lst );
1453 return;
1454 }
1455
1456 m_strPath_encoded = QString::null;
1457
1458 if ( _txt.isEmpty() )
1459 return;
1460
1461 int i = 0;
1462 int len = m_strPath.length();
1463 // NB: avoid three '/' when building a new path from nothing
1464 if ( len == 0 ) {
1465 while( _txt[i] == '/' ) ++i;
1466 }
1467 // Add the trailing '/' if it is missing
1468 else if ( _txt[0] != '/' && ( len == 0 || m_strPath[ len - 1 ] != '/' ) )
1469 m_strPath += "/";
1470
1471 // No double '/' characters
1472 i = 0;
1473 if ( len != 0 && m_strPath[ len - 1 ] == '/' )
1474 {
1475 while( _txt[i] == '/' )
1476 ++i;
1477 }
1478
1479 m_strPath += _txt.mid( i );
1480}
1481
1482QString KURL::directory( bool _strip_trailing_slash_from_result,
1483 bool _ignore_trailing_slash_in_path ) const
1484{
1485 QString result = m_strPath_encoded.isEmpty() ? m_strPath : m_strPath_encoded;
1486 if ( _ignore_trailing_slash_in_path )
1487 result = trailingSlash( -1, result );
1488
1489 if ( result.isEmpty() || result == "/" )
1490 return result;
1491
1492 int i = result.findRev( "/" );
1493 // If ( i == -1 ) => the first character is not a '/'
1494 // So it's some URL like file:blah.tgz, with no path
1495 if ( i == -1 )
1496 return QString::null;
1497
1498 if ( i == 0 )
1499 {
1500 result = "/";
1501 return result;
1502 }
1503
1504 if ( _strip_trailing_slash_from_result )
1505 result = result.left( i );
1506 else
1507 result = result.left( i + 1 );
1508
1509 if (!m_strPath_encoded.isEmpty())
1510 result = decode(result);
1511
1512 return result;
1513}
1514
1515
1516bool KURL::cd( const QString& _dir )
1517{
1518 if ( _dir.isEmpty() || m_bIsMalformed )
1519 return false;
1520
1521 if (hasSubURL())
1522 {
1523 KURL::List lst = split( *this );
1524 KURL &u = lst.last();
1525 u.cd(_dir);
1526 *this = join( lst );
1527 return true;
1528 }
1529
1530 // absolute path ?
1531 if ( _dir[0] == '/' )
1532 {
1533 m_strPath_encoded = QString::null;
1534 m_strPath = _dir;
1535 setHTMLRef( QString::null );
1536 m_strQuery_encoded = QString::null;
1537 return true;
1538 }
1539
1540 // Users home directory on the local disk ?
1541 if ( ( _dir[0] == '~' ) && ( m_strProtocol == fileProt ))
1542 {
1543 m_strPath_encoded = QString::null;
1544 m_strPath = QDir::homeDirPath();
1545 m_strPath += "/";
1546 m_strPath += _dir.right(m_strPath.length() - 1);
1547 setHTMLRef( QString::null );
1548 m_strQuery_encoded = QString::null;
1549 return true;
1550 }
1551
1552 // relative path
1553 // we always work on the past of the first url.
1554 // Sub URLs are not touched.
1555
1556 // append '/' if necessary
1557 QString p = path(1);
1558 p += _dir;
1559 p = cleanpath( p );
1560 setPath( p );
1561
1562 setHTMLRef( QString::null );
1563 m_strQuery_encoded = QString::null;
1564
1565 return true;
1566}
1567
1568KURL KURL::upURL( ) const
1569{
1570 if (!query().isEmpty())
1571 {
1572 KURL u(*this);
1573 u.setQuery(QString::null);
1574 return u;
1575 };
1576
1577 if (!hasSubURL())
1578 {
1579 KURL u(*this);
1580 u.cd("../");
1581 return u;
1582 }
1583
1584 // We have a subURL.
1585 KURL::List lst = split( *this );
1586 if (lst.isEmpty())
1587 return KURL(); // Huh?
1588 while (true)
1589 {
1590 KURL &u = lst.last();
1591 QString old = u.path();
1592 u.cd("../");
1593 if (u.path() != old)
1594 break; // Finshed.
1595 if (lst.count() == 1)
1596 break; // Finished.
1597 lst.remove(lst.fromLast());
1598 }
1599 return join( lst );
1600}
1601
1602QString KURL::htmlRef() const
1603{
1604 if ( !hasSubURL() )
1605 {
1606 return decode( ref() );
1607 }
1608
1609 List lst = split( *this );
1610 return decode( (*lst.begin()).ref() );
1611}
1612
1613QString KURL::encodedHtmlRef() const
1614{
1615 if ( !hasSubURL() )
1616 {
1617 return ref();
1618 }
1619
1620 List lst = split( *this );
1621 return (*lst.begin()).ref();
1622}
1623
1624void KURL::setHTMLRef( const QString& _ref )
1625{
1626 if ( !hasSubURL() )
1627 {
1628 m_strRef_encoded = encode( _ref, true, 0 /*?*/);
1629 return;
1630 }
1631
1632 List lst = split( *this );
1633
1634 (*lst.begin()).setRef( encode( _ref, true, 0 /*?*/) );
1635
1636 *this = join( lst );
1637}
1638
1639bool KURL::hasHTMLRef() const
1640{
1641 if ( !hasSubURL() )
1642 {
1643 return hasRef();
1644 }
1645
1646 List lst = split( *this );
1647 return (*lst.begin()).hasRef();
1648}
1649
1650void
1651KURL::setProtocol( const QString& _txt )
1652{
1653 m_strProtocol = _txt;
1654 m_bIsMalformed = false;
1655}
1656
1657void
1658KURL::setUser( const QString& _txt )
1659{
1660 m_strUser = _txt;
1661}
1662
1663void
1664KURL::setPass( const QString& _txt )
1665{
1666 m_strPass = _txt;
1667}
1668
1669void
1670KURL::setHost( const QString& _txt )
1671{
1672#ifndef KDE_QT_ONLY
1673 m_strHost = KIDNA::toUnicode(_txt);
1674 if (m_strHost.isEmpty())
1675 m_strHost = _txt.lower(); // Probably an invalid hostname, but...
1676#else
1677 m_strHost = _txt.lower();
1678#endif
1679}
1680
1681void
1682KURL::setPort( unsigned short int _p )
1683{
1684 m_iPort = _p;
1685}
1686
1687void KURL::setPath( const QString & path )
1688{
1689 if (isEmpty())
1690 m_bIsMalformed = false;
1691 if (m_strProtocol.isEmpty())
1692 {
1693 m_strProtocol = fileProt;
1694 }
1695 m_strPath = path;
1696 m_strPath_encoded = QString::null;
1697}
1698
1699void KURL::setDirectory( const QString &dir)
1700{
1701//US this has to be fixed. endsWith is not available in my distribution
1702//US if ( dir.endsWith("/"))
1703//US setPath(dir);
1704//US else
1705 setPath(dir+"/");
1706}
1707
1708void KURL::setQuery( const QString &_txt, int encoding_hint)
1709{
1710 if (!_txt.length())
1711 {
1712 m_strQuery_encoded = _txt;
1713 return;
1714 }
1715 if (_txt[0] =='?')
1716 m_strQuery_encoded = _txt.mid(1);
1717 else
1718 m_strQuery_encoded = _txt;
1719
1720 int l = m_strQuery_encoded.length();
1721 int i = 0;
1722 QString result;
1723 while (i < l)
1724 {
1725 int s = i;
1726 // Re-encode. Break encoded string up according to the reserved
1727 // characters '&:;=/?' and re-encode part by part.
1728 while(i < l)
1729 {
1730 char c = m_strQuery_encoded[i].latin1();
1731 if ((c == '&') || (c == ':') || (c == ';') ||
1732 (c == '=') || (c == '/') || (c == '?'))
1733 break;
1734 i++;
1735 }
1736 if (i > s)
1737 {
1738 QString tmp = m_strQuery_encoded.mid(s, i-s);
1739 QString newTmp;
1740 decode( tmp, newTmp, tmp, encoding_hint, false );
1741 result += tmp;
1742 }
1743 if (i < l)
1744 {
1745 result += m_strQuery_encoded[i];
1746 i++;
1747 }
1748 }
1749 m_strQuery_encoded = result;
1750}
1751
1752QString KURL::query() const
1753{
1754 if (m_strQuery_encoded.isNull())
1755 return QString::null;
1756 return '?'+m_strQuery_encoded;
1757}
1758
1759QString KURL::decode_string(const QString &str, int encoding_hint)
1760{
1761 return decode(str, encoding_hint);
1762}
1763
1764QString KURL::encode_string(const QString &str, int encoding_hint)
1765{
1766 return encode(str, false, encoding_hint);
1767}
1768
1769QString KURL::encode_string_no_slash(const QString &str, int encoding_hint)
1770{
1771 return encode(str, true, encoding_hint);
1772}
1773
1774bool urlcmp( const QString& _url1, const QString& _url2 )
1775{
1776 // Both empty ?
1777 if ( _url1.isEmpty() && _url2.isEmpty() )
1778 return true;
1779 // Only one empty ?
1780 if ( _url1.isEmpty() || _url2.isEmpty() )
1781 return false;
1782
1783 KURL::List list1 = KURL::split( _url1 );
1784 KURL::List list2 = KURL::split( _url2 );
1785
1786 // Malformed ?
1787 if ( list1.isEmpty() || list2.isEmpty() )
1788 return false;
1789
1790 return ( list1 == list2 );
1791}
1792
1793bool urlcmp( const QString& _url1, const QString& _url2, bool _ignore_trailing, bool _ignore_ref )
1794{
1795 // Both empty ?
1796 if ( _url1.isEmpty() && _url2.isEmpty() )
1797 return true;
1798 // Only one empty ?
1799 if ( _url1.isEmpty() || _url2.isEmpty() )
1800 return false;
1801
1802 KURL::List list1 = KURL::split( _url1 );
1803 KURL::List list2 = KURL::split( _url2 );
1804
1805 // Malformed ?
1806 if ( list1.isEmpty() || list2.isEmpty() )
1807 return false;
1808
1809 unsigned int size = list1.count();
1810 if ( list2.count() != size )
1811 return false;
1812
1813 if ( _ignore_ref )
1814 {
1815 (*list1.begin()).setRef(QString::null);
1816 (*list2.begin()).setRef(QString::null);
1817 }
1818
1819 KURL::List::Iterator it1 = list1.begin();
1820 KURL::List::Iterator it2 = list2.begin();
1821 for( ; it1 != list1.end() ; ++it1, ++it2 )
1822 if ( !(*it1).equals( *it2, _ignore_trailing ) )
1823 return false;
1824
1825 return true;
1826}
1827/*US we do not need this functions
1828
1829QMap< QString, QString > KURL::queryItems( int options ) const {
1830 return queryItems(options, 0);
1831}
1832
1833QMap< QString, QString > KURL::queryItems( int options, int encoding_hint ) const {
1834 if ( m_strQuery_encoded.isEmpty() )
1835 return QMap<QString,QString>();
1836
1837 QMap< QString, QString > result;
1838 QStringList items = QStringList::split( '&', m_strQuery_encoded );
1839 for ( QStringList::const_iterator it = items.begin() ; it != items.end() ; ++it ) {
1840 int equal_pos = (*it).find( '=' );
1841 if ( equal_pos > 0 ) { // = is not the first char...
1842 QString name = (*it).left( equal_pos );
1843 if ( options & CaseInsensitiveKeys )
1844 name = name.lower();
1845 QString value = (*it).mid( equal_pos + 1 );
1846 if ( value.isEmpty() )
1847 result.insert( name, QString::fromLatin1("") );
1848 else {
1849 // ### why is decoding name not neccessary?
1850 value.replace( '+', ' ' ); // + in queries means space
1851 result.insert( name, decode_string( value, encoding_hint ) );
1852 }
1853 } else if ( equal_pos < 0 ) { // no =
1854 QString name = (*it);
1855 if ( options & CaseInsensitiveKeys )
1856 name = name.lower();
1857 result.insert( name, QString::null );
1858 }
1859 }
1860
1861 return result;
1862}
1863
1864QString KURL::queryItem( const QString& _item ) const
1865{
1866 return queryItem( _item, 0 );
1867}
1868
1869QString KURL::queryItem( const QString& _item, int encoding_hint ) const
1870{
1871 QString item = _item + '=';
1872 if ( m_strQuery_encoded.length() <= 1 )
1873 return QString::null;
1874
1875 QStringList items = QStringList::split( '&', m_strQuery_encoded );
1876 unsigned int _len = item.length();
1877 for ( QStringList::ConstIterator it = items.begin(); it != items.end(); ++it )
1878 {
1879 if ( (*it).startsWith( item ) )
1880 {
1881 if ( (*it).length() > _len )
1882 {
1883 QString str = (*it).mid( _len );
1884 str.replace( '+', ' ' ); // + in queries means space.
1885 return decode_string( str, encoding_hint );
1886 }
1887 else // empty value
1888 return QString::fromLatin1("");
1889 }
1890 }
1891
1892 return QString::null;
1893}
1894US we do not need this functions*/
1895
1896void KURL::removeQueryItem( const QString& _item )
1897{
1898 QString item = _item + '=';
1899 if ( m_strQuery_encoded.length() <= 1 )
1900 return;
1901
1902 QStringList items = QStringList::split( '&', m_strQuery_encoded );
1903 for ( QStringList::Iterator it = items.begin(); it != items.end(); )
1904 {
1905 if ( (*it).startsWith( item ) || (*it == _item) )
1906 {
1907 QStringList::Iterator deleteIt = it;
1908 ++it;
1909 items.remove(deleteIt);
1910 }
1911 else
1912 {
1913 ++it;
1914 }
1915 }
1916 m_strQuery_encoded = items.join( "&" );
1917}
1918
1919void KURL::addQueryItem( const QString& _item, const QString& _value, int encoding_hint )
1920{
1921 QString item = _item + '=';
1922 QString value = encode( _value, true, encoding_hint );
1923
1924 if (!m_strQuery_encoded.isEmpty())
1925 m_strQuery_encoded += '&';
1926 m_strQuery_encoded += item + value;
1927}
1928
1929// static
1930KURL KURL::fromPathOrURL( const QString& text )
1931{
1932 if ( text.isEmpty() )
1933 return KURL();
1934
1935 KURL url;
1936 if ( text[0] == '/' )
1937 url.setPath( text );
1938 else
1939 url = text;
1940
1941 return url;
1942}
diff --git a/microkde/kurl.h b/microkde/kurl.h
new file mode 100644
index 0000000..cd65a1c
--- a/dev/null
+++ b/microkde/kurl.h
@@ -0,0 +1,853 @@
1/* This file is part of the KDE libraries
2 * Copyright (C) 1999 Torben Weis <weis@kde.org>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public License
15 * along with this library; see the file COPYING.LIB. If not, write to
16 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
18 **/
19
20#ifndef __kurl_h__
21#define __kurl_h__ "$Id$"
22
23#include <qstring.h>
24#include <qvaluelist.h>
25
26class QUrl;
27class QStringList;
28template <typename K, typename V> class QMap;
29
30class KURLPrivate;
31/**
32 * Represents and parses a URL.
33 *
34 * A prototypical URL looks like:
35 * <pre>
36 * protocol:/user:password\@hostname:port/path/to/file.ext#reference
37 * </pre>
38 *
39 * KURL has some restrictions regarding the path
40 * encoding. KURL works internally with the decoded path and
41 * and encoded query. For example,
42 * <pre>
43 * http://localhost/cgi-bin/test%20me.pl?cmd=Hello%20you
44 * </pre>
45 * would result in a decoded path "/cgi-bin/test me.pl"
46 * and in the encoded query "?cmd=Hello%20you".
47 * Since path is internally always encoded you may @em not use
48 * "%00" in the path, although this is OK for the query.
49 *
50 * @author Torben Weis <weis@kde.org>
51 */
52class KURL
53{
54public:
55 enum AdjustementFlags
56 {
57 NoAdjustements = 0,
58 StripFileProtocol = 1
59 };
60
61 /**
62 * KURL::List is a QValueList that contains KURLs with a few
63 * convenience methods.
64 * @see KURL
65 * @see QValueList
66 */
67 class List : public QValueList<KURL>
68 {
69 public:
70 /**
71 * Creates an empty List.
72 */
73 List() { }
74 /**
75 * Creates a list that contains the given URL as only
76 * item.
77 * @param url the url to add.
78 */
79 List(const KURL &url);
80 /**
81 * Creates a list that contains the URLs from the given
82 * list.
83 * @param list the list containing the URLs as strings
84 */
85 List(const QStringList &list);
86 /**
87 * Converts the URLs of this list to a list of strings.
88 * @return the list of strings
89 */
90 QStringList toStringList() const;
91 };
92 /**
93 * Constructs an empty URL.
94 */
95 KURL();
96
97 /**
98 * Destructs the KURL object.
99 */
100 ~KURL();
101
102 /**
103 * Usual constructor, to construct from a string.
104 * @param url A URL, not a filename. If the URL does not have a protocol
105 * part, "file:" is assumed.
106 * It is dangerous to feed unix filenames into this function,
107 * this will work most of the time but not always.
108 * For example "/home/Torben%20Weis" will be considered a URL
109 * pointing to the file "/home/Torben Weis" instead of to the
110 * file "/home/Torben%20Weis".
111 * This means that if you have a usual UNIX like path you
112 * should not use this constructor.
113 * Instead create an empty url and set the path by using
114 * @ref setPath().
115 * @param encoding_hint MIB of original encoding of URL.
116 * @see QTextCodec::mibEnum()
117 */
118 KURL( const QString& url, int encoding_hint = 0 );
119 /**
120 * Constructor taking a char * @p url, which is an _encoded_ representation
121 * of the URL, exactly like the usual constructor. This is useful when
122 * then URL, in its encoded form, is strictly ascii.
123 * @param url A encoded URL. If the URL does not have a protocol part,
124 * "file:" is assumed.
125 * @param encoding_hint MIB of original encoding of URL.
126 * @see QTextCodec::mibEnum()
127 */
128 KURL( const char * url, int encoding_hint = 0 );
129 /**
130 * Constructor taking a QCString @p url, which is an _encoded_ representation
131 * of the URL, exactly like the usual constructor. This is useful when
132 * then URL, in its encoded form, is strictly ascii.
133 * @param url A encoded URL. If the URL does not have a protocol part,
134 * "file:" is assumed.
135 * @param encoding_hint MIB of original encoding of URL.
136 * @see QTextCodec::mibEnum()
137 */
138 KURL( const QCString& url, int encoding_hint = 0 );
139 /**
140 * Copy constructor.
141 * @param u the KURL to copy
142 */
143 KURL( const KURL& u );
144 /**
145 * Converts from a @ref QUrl.
146 * @param u the QUrl
147 */
148 KURL( const QUrl &u );
149 /**
150 * Constructor allowing relative URLs.
151 *
152 * @param _baseurl The base url.
153 * @param _rel_url A relative or absolute URL.
154 * If this is an absolute URL then @p _baseurl will be ignored.
155 * If this is a relative URL it will be combined with @p _baseurl.
156 * Note that _rel_url should be encoded too, in any case.
157 * So do NOT pass a path here (use setPath or addPath instead).
158 * @param encoding_hint MIB of original encoding of URL.
159 * @see QTextCodec::mibEnum()
160 */
161 KURL( const KURL& _baseurl, const QString& _rel_url, int encoding_hint=0 );
162
163 /**
164 * Returns the protocol for the URL (i.e., file, http, etc.).
165 * @return the protocol of the URL, does not include the colon. If the
166 * URL is malformed, QString::null will be returned.
167 **/
168 QString protocol() const { return m_bIsMalformed ? QString::null : m_strProtocol; }
169 /**
170 * Sets the protocol for the URL (i.e., file, http, etc.)
171 * @param _txt the new protocol of the URL (without colon)
172 **/
173 void setProtocol( const QString& _txt );
174
175 /**
176 * Returns the decoded user name (login, user id, ...) included in the URL.
177 * @return the user name or QString::null if there is no user name
178 **/
179 QString user() const { return m_strUser; }
180 /**
181 * Sets the user name (login, user id, ...) included in the URL.
182 *
183 * Special characters in the user name will appear encoded in the URL.
184 * @param _txt the name of the user or QString::null to remove the user
185 **/
186 void setUser( const QString& _txt );
187 /**
188 * Test to see if this URL has a user name included in it.
189 * @return true if the URL has an non-empty user name
190 **/
191 bool hasUser() const { return !m_strUser.isEmpty(); }
192
193 /**
194 * Returns the decoded password (corresponding to \ref user()) included in the URL.
195 * @return the password or QString::null if it does not exist
196 **/
197 QString pass() const { return m_strPass; }
198 /**
199 * Sets the password (corresponding to @ref user()) included in the URL.
200 *
201 * Special characters in the password will appear encoded in the URL.
202 * Note that a password can only appear in a URL string if you also set
203 * a user.
204 * @param _txt the password to set or QString::null to remove the password
205 * @see #setUser
206 * @see #hasUser
207 **/
208 void setPass( const QString& _txt );
209 /**
210 * Test to see if this URL has a password included in it.
211 * @return true if there is a non-empty password set
212 **/
213 bool hasPass() const { return !m_strPass.isEmpty(); }
214
215 /**
216 * Returns the decoded hostname included in the URL.
217 * @return the name of the host or QString::null if no host is set
218 **/
219 QString host() const { return m_strHost; }
220
221 /**
222 * Sets the hostname included in the URL.
223 *
224 * Special characters in the hostname will appear encoded in the URL.
225 * @param _txt the new name of the host or QString::null to remove the host
226 **/
227 void setHost( const QString& _txt );
228 /**
229 * Test to see if this URL has a hostname included in it.
230 * @return true if the URL has a host
231 **/
232 bool hasHost() const { return !m_strHost.isEmpty(); }
233
234 /**
235 * Returns the port number included in the URL.
236 * @return the port number. If there is no port number specified in the
237 * URL, returns 0.
238 **/
239 unsigned short int port() const { return m_iPort; }
240 /**
241 * Sets the port number included in the URL.
242 * @param _p the new port number or 0 to have no port number
243 **/
244 void setPort( unsigned short int _p );
245
246 /**
247 * Returns the current decoded path. This does @em not include the query.
248 * @return the path of the URL (without query), or QString::null if no
249 * path set.
250 */
251 QString path() const { return m_strPath; }
252
253 /**
254 * @param _trailing May be ( -1, 0 +1 ). -1 strips a trailing '/', +1 adds
255 * a trailing '/' if there is none yet and 0 returns the
256 * path unchanged. If the URL has no path, then no '/' is added
257 * anyway. And on the other side: If the path is "/", then this
258 * character won't be stripped. Reason: "ftp://weis\@host" means something
259 * completely different than "ftp://weis\@host/". So adding or stripping
260 * the '/' would really alter the URL, while "ftp://host/path" and
261 * "ftp://host/path/" mean the same directory.
262 *
263 * @return The current decoded path. This does not include the query. Can
264 * be QString::null if no path is set.
265 */
266 QString path( int _trailing ) const;
267
268 /**
269 * Sets the path of the URL. The query is not changed by this function.
270 *
271 * @param path The new path. This is considered to be decoded. This
272 * means: %3f does not become decoded
273 * and the ? does not indicate the start of the query part.
274 * Can be QString::null to delete the path.
275 */
276 void setPath( const QString& path );
277
278 /**
279 * Test to see if this URL has a path is included in it.
280 * @return true if there is a path
281 **/
282 bool hasPath() const { return !m_strPath.isEmpty(); }
283
284 /**
285 * Resolves "." and ".." components in path.
286 * Some servers seem not to like the removal of extra '/'
287 * even though it is against the specification in RFC 2396.
288 *
289 * @param cleanDirSeparator if true, occurrances of consecutive
290 * directory separators (e.g. /foo//bar) are cleaned up as well.
291 */
292 void cleanPath(bool cleanDirSeparator = true);
293
294 /**
295 * Add or remove a trailing slash to/from the path.
296 * @param _trailing May be ( -1, 0 +1 ). -1 strips a trailing '/', +1 adds
297 * a trailing '/' if there is none yet and 0 returns the
298 * path unchanged. If the URL has no path, then no '/' is added
299 * anyway. And on the other side: If the path is "/", then this
300 * character won't be stripped. Reason: "ftp://weis\@host" means something
301 * completely different than "ftp://weis\@host/". So adding or stripping
302 * the '/' would really alter the URL, while "ftp://host/path" and
303 * "ftp://host/path/" mean the same directory.
304 */
305 void adjustPath(int _trailing);
306
307 /**
308 * This is useful for HTTP. It looks first for '?' and decodes then.
309 * The encoded path is the concatenation of the current path and the query.
310 * @param _txt the new path and query.
311 * @param encoding_hint MIB of original encoding of @p _txt .
312 * @see QTextCodec::mibEnum()
313 */
314 void setEncodedPathAndQuery( const QString& _txt, int encoding_hint = 0 );
315
316 /**
317 * Sets the (already encoded) path
318 * @param _txt the new path
319 * @param encoding_hint MIB of original encoding of @p _txt .
320 * @see QTextCodec::mibEnum()
321 */
322 void setEncodedPath(const QString& _txt, int encoding_hint = 0 );
323
324 /**
325 * Returns the encoded path and the query.
326 *
327 * @param _trailing May be ( -1, 0 +1 ). -1 strips a trailing '/', +1 adds
328 * a trailing '/' if there is none yet and 0 returns the
329 * path unchanged. If the URL has no path, then no '/' is added
330 * anyway. And on the other side: If the path is "/", then this
331 * character won't be stripped. Reason: "ftp://weis\@host" means something
332 * completely different than "ftp://weis\@host/". So adding or stripping
333 * the '/' would really alter the URL, while "ftp://host/path" and
334 * "ftp://host/path/" mean the same directory.
335 * @param _no_empty_path If set to true then an empty path is substituted by "/".
336 * @param encoding_hint MIB of desired encoding of URL.
337 * @see QTextCodec::mibEnum()
338 * @return The concatenation if the encoded path , '?' and the encoded query.
339 *
340 */
341 QString encodedPathAndQuery( int _trailing = 0, bool _no_empty_path = false, int encoding_hint = 0) const;
342
343 /**
344 * @param _txt This is considered to be encoded. This has a good reason:
345 * The query may contain the 0 character.
346 *
347 * The query should start with a '?'. If it doesn't '?' is prepended.
348 * @param encoding_hint Reserved, should be 0.
349 * @see QTextCodec::mibEnum()
350 */
351 void setQuery( const QString& _txt, int encoding_hint = 0);
352
353 /**
354 * Returns the query of the URL.
355 * The query may contain the 0 character.
356 * If a query is present it always starts with a '?'.
357 * A single '?' means an empty query.
358 * An empty string means no query.
359 * @return The encoded query, or QString::null if there is none.
360 */
361 QString query() const;
362
363 /**
364 * The reference is @em never decoded automatically.
365 * @return the undecoded reference, or QString::null if there is none
366 */
367 QString ref() const { return m_strRef_encoded; }
368
369 /**
370 * Sets the reference part (everything after '#').
371 * @param _txt The encoded reference (or QString::null to remove it).
372 */
373 void setRef( const QString& _txt ) { m_strRef_encoded = _txt; }
374
375 /**
376 * Checks whether the URL has a reference part.
377 * @return true if the URL has a reference part. In a URL like
378 * http://www.kde.org/kdebase.tar#tar:/README it would
379 * return true, too.
380 */
381 bool hasRef() const { return !m_strRef_encoded.isNull(); }
382
383 /**
384 * Returns the HTML reference (the part of the URL after "#").
385 * @return The HTML-style reference.
386 * @see #split
387 * @see #hasSubURL
388 * @see #encodedHtmlRef
389 */
390 QString htmlRef() const;
391
392 /**
393 * Returns the HTML reference (the part of the URL after "#") in
394 * encoded form.
395 * @return The HTML-style reference in its original form.
396 */
397 QString encodedHtmlRef() const;
398
399 /**
400 * Sets the HTML-style reference.
401 *
402 * @param _ref The new reference. This is considered to be @em not encoded in
403 * contrast to @ref setRef(). Use QString::null to remove it.
404 * @see htmlRef()
405 */
406 void setHTMLRef( const QString& _ref );
407
408 /**
409 * Checks whether there is a HTML reference.
410 * @return true if the URL has an HTML-style reference.
411 * @see htmlRef()
412 */
413 bool hasHTMLRef() const;
414
415 /**
416 * Checks whether the URL is well formed.
417 * @return false if the URL is malformed. This function does @em not test
418 * whether sub URLs are well-formed, too.
419 */
420 bool isValid() const { return !m_bIsMalformed; }
421 /**
422 * @deprecated
423 */
424 bool isMalformed() const { return !isValid(); }
425
426 /**
427 * Checks whether the file is local.
428 * @return true if the file is a plain local file and has no filter protocols
429 * attached to it.
430 */
431 bool isLocalFile() const;
432
433 /**
434 * Adds encoding information to url by adding a "charset" parameter. If there
435 * is already a charset parameter, it will be replaced.
436 * @param encoding the encoding to add or QString::null to remove the
437 * encoding.
438 */
439 void setFileEncoding(const QString &encoding);
440
441 /**
442 * Returns encoding information from url, the content of the "charset"
443 * parameter.
444 * @return An encoding suitable for QTextCodec::codecForName()
445 * or QString::null if not encoding was specified.
446 */
447 QString fileEncoding() const;
448
449 /**
450 * Checks whether the URL has any sub URLs. See @ref #split()
451 * for examples for sub URLs.
452 * @return true if the file has at least one sub URL.
453 * @see #split
454 */
455 bool hasSubURL() const;
456
457 /**
458 * Adds to the current path.
459 * Assumes that the current path is a directory. @p _txt is appended to the
460 * current path. The function adds '/' if needed while concatenating.
461 * This means it does not matter whether the current path has a trailing
462 * '/' or not. If there is none, it becomes appended. If @p _txt
463 * has a leading '/' then this one is stripped.
464 *
465 * @param _txt The text to add. It is considered to be decoded.
466 */
467 void addPath( const QString& _txt );
468
469 /**
470 * Returns the value of a certain query item.
471 *
472 * @param _item Item whose value we want
473 * @param encoding_hint MIB of encoding of query.
474 *
475 * @return the value of the given query item name or QString::null if the
476 * specified item does not exist.
477 */
478/*US we do not need this functions
479 QString queryItem( const QString& _item ) const;
480 QString queryItem( const QString& _item, int encoding_hint ) const;
481*/
482 /**
483 * Options for @ref #queryItems. Currently, only one option is
484 * defined:
485 *
486 * @param CaseInsensitiveKeys normalize query keys to lowercase.
487 *
488 * @since 3.1
489 **/
490 enum QueryItemsOptions { CaseInsensitiveKeys = 1 };
491
492 /**
493 * Returns the list of query items as a map mapping keys to values.
494 *
495 * @param options any of @ref QueryItemsOptions <em>or</or>ed together.
496 * @param encoding_hint MIB of encoding of query.
497 *
498 * @return the map of query items or the empty map if the url has no
499 * query items.
500 *
501 * @since 3.1
502 */
503 QMap< QString, QString > queryItems( int options=0 ) const;
504 QMap< QString, QString > queryItems( int options, int encoding_hint ) const;
505
506 /**
507 * Add an additional query item.
508 * To replace an existing query item, the item should first be
509 * removed with @ref removeQueryItem()
510 *
511 * @param _item Name of item to add
512 * @param _value Value of item to add
513 * @param encoding_hint MIB of encoding to use for _value.
514 * @see QTextCodec::mibEnum()
515 */
516 void addQueryItem( const QString& _item, const QString& _value, int encoding_hint = 0 );
517
518 /**
519 * Remove an item from the query.
520 *
521 * @param _item Item to be removed
522 */
523 void removeQueryItem( const QString& _item );
524
525 /**
526 * Sets the filename of the path.
527 * In comparison to @ref addPath() this function does not assume that the current
528 * path is a directory. This is only assumed if the current path ends with '/'.
529 *
530 * Any reference is reset.
531 *
532 * @param _txt The filename to be set. It is considered to be decoded. If the
533 * current path ends with '/' then @p _txt int just appended, otherwise
534 * all text behind the last '/' in the current path is erased and
535 * @p _txt is appended then. It does not matter whether @p _txt starts
536 * with '/' or not.
537 */
538 void setFileName( const QString&_txt );
539
540 /**
541 * Returns the filename of the path.
542 * @param _ignore_trailing_slash_in_path This tells whether a trailing '/' should
543 * be ignored. This means that the function would return "torben" for
544 * <tt>file:/hallo/torben/</tt> and <tt>file:/hallo/torben</tt>.
545 * If the flag is set to false, then everything behind the last '/'
546 * is considered to be the filename.
547 * @return The filename of the current path. The returned string is decoded. Null
548 * if there is no file (and thus no path).
549 */
550 QString fileName( bool _ignore_trailing_slash_in_path = true ) const;
551
552 /**
553 * Returns the directory of the path.
554 * @param _strip_trailing_slash_from_result tells whether the returned result should end with '/' or not.
555 * If the path is empty or just "/" then this flag has no effect.
556 * @param _ignore_trailing_slash_in_path means that <tt>file:/hallo/torben</tt> and
557 * <tt>file:/hallo/torben/"</tt> would both return <tt>/hallo/</tt>
558 * or <tt>/hallo</tt> depending on the other flag
559 * @return The directory part of the current path. Everything between the last and the second last '/'
560 * is returned. For example <tt>file:/hallo/torben/</tt> would return "/hallo/torben/" while
561 * <tt>file:/hallo/torben</tt> would return "hallo/". The returned string is decoded. QString::null is returned when there is no path.
562 */
563 QString directory( bool _strip_trailing_slash_from_result = true,
564 bool _ignore_trailing_slash_in_path = true ) const;
565
566 /**
567 * Set the directory to @p dir, leaving the filename empty.
568 */
569 void setDirectory(const QString &dir);
570
571 /**
572 * Changes the directory by descending into the given directory.
573 * It is assumed the current URL represents a directory.
574 * If @p dir starts with a "/" the
575 * current URL will be "protocol://host/dir" otherwise @p _dir will
576 * be appended to the path. @p _dir can be ".."
577 * This function won't strip protocols. That means that when you are in
578 * file:/dir/dir2/my.tgz#tar:/ and you do cd("..") you will
579 * still be in file:/dir/dir2/my.tgz#tar:/
580 *
581 * @param _dir the directory to change to
582 * @return true if successful
583 */
584 bool cd( const QString& _dir );
585
586 /**
587 * Returns the URL as string, with all escape sequences intact,
588 * encoded in a given charset.
589 * This is used in particular for encoding URLs in UTF-8 before using them
590 * in a drag and drop operation.
591 * Please note that the string returned by @ref url() will include
592 * the password of the URL. If you want to show the URL to the
593 * user, use @ref prettyURL().
594 *
595 * @param _trailing This may be ( -1, 0 +1 ). -1 strips a trailing '/' from the path, +1 adds
596 * a trailing '/' if there is none yet and 0 returns the
597 * path unchanged.
598 * @param encoding_hint MIB of encoding to use.
599 * @return The complete URL, with all escape sequences intact, encoded
600 * in a given charset.
601 * @see QTextCodec::mibEnum()
602 * @see prettyURL()
603 */
604 QString url( int _trailing = 0, int encoding_hint = 0) const;
605
606 /**
607 * Returns the URL as string in human-friendly format.
608 * Example:
609 * <pre>
610 * http://localhost:8080/test.cgi?test=hello world&name=fred
611 * </pre>
612 * @param _trailing -1 to strip a trailing '/' from the path, +1 adds
613 * a trailing '/' if there is none yet and 0 returns the
614 * path unchanged.
615 * @return A human readable URL, with no non-necessary encodings/escaped
616 * characters. Password will not be shown.
617 * @see url()
618 */
619 QString prettyURL( int _trailing = 0) const;
620
621
622 /**
623 * Returns the URL as string, escaped for HTML.
624 * @return A human readable URL, with no non-necessary encodings/escaped
625 * characters which is html encoded for safe inclusion in html or
626 * rich text. Password will not be shown.
627 */
628 QString htmlURL() const;
629
630 /**
631 * Returns the URL as string, escaped for HTML.
632 * Example:
633 * <pre>
634 * http://localhost:8080/test.cgi?test=hello world&name=fred
635 * </pre>
636 * @return A human readable URL, with no non-necessary encodings/escaped
637 * characters. Password will not be shown.
638 */
639 QString prettyURL( int _trailing, AdjustementFlags _flags) const;
640 // ### BIC: Merge the two above
641
642 /**
643 * Test to see if the KURL is empty.
644 * @return true if the URL is empty
645 **/
646 bool isEmpty() const;
647
648 /**
649 * This function is useful to implement the "Up" button in a file manager for example.
650 * @ref cd() never strips a sub-protocol. That means that if you are in
651 * file:/home/x.tgz#gzip:/#tar:/ and hit the up button you expect to see
652 * file:/home. The algorithm tries to go up on the right-most URL. If that is not
653 * possible it strips the right most URL. It continues stripping URLs.
654 * @return a URL that is a level higher
655 */
656 KURL upURL( ) const;
657
658 KURL& operator=( const KURL& _u );
659 KURL& operator=( const QString& _url );
660 KURL& operator=( const char * _url );
661 KURL& operator=( const QUrl & u );
662
663 bool operator==( const KURL& _u ) const;
664 bool operator==( const QString& _u ) const;
665 bool operator!=( const KURL& _u ) const { return !( *this == _u ); }
666 bool operator!=( const QString& _u ) const { return !( *this == _u ); }
667
668 /**
669 * The same as equals(), just with a less obvious name.
670 * Compares this url with @p u.
671 * @param ignore_trailing set to true to ignore trailing '/' characters.
672 * @return true if both urls are the same
673 * @see operator==. This function should be used if you want to
674 * ignore trailing '/' characters.
675 * @deprecated
676 */
677 bool cmp( const KURL &u, bool ignore_trailing = false ) const;
678
679 /**
680 * Compares this url with @p u.
681 * @param ignore_trailing set to true to ignore trailing '/' characters.
682 * @return true if both urls are the same
683 * @see operator==. This function should be used if you want to
684 * ignore trailing '/' characters.
685 * @since 3.1
686 */
687 bool equals( const KURL &u, bool ignore_trailing = false ) const;
688
689 /**
690 * Checks whether the given URL is parent of this URL.
691 * For instance, ftp://host/dir/ is a parent of ftp://host/dir/subdir/subsubdir/.
692 * @return true if this url is a parent of @p u (or the same URL as @p u)
693 */
694 bool isParentOf( const KURL& u ) const;
695
696 /**
697 * Splits nested URLs like file:/home/weis/kde.tgz#gzip:/#tar:/kdebase
698 * A URL like http://www.kde.org#tar:/kde/README.hml#ref1 will be split in
699 * http://www.kde.org and tar:/kde/README.html#ref1.
700 * That means in turn that "#ref1" is an HTML-style reference and not a new sub URL.
701 * Since HTML-style references mark
702 * a certain position in a document this reference is appended to every URL.
703 * The idea behind this is that browsers, for example, only look at the first URL while
704 * the rest is not of interest to them.
705 *
706 *
707 * @param _url The URL that has to be split.
708 * @return An empty list on error or the list of split URLs.
709 * @see #hasSubURL
710 */
711 static List split( const QString& _url );
712
713 /**
714 * Splits nested URLs like file:/home/weis/kde.tgz#gzip:/#tar:/kdebase
715 * A URL like http://www.kde.org#tar:/kde/README.hml#ref1 will be split in
716 * http://www.kde.org and tar:/kde/README.html#ref1.
717 * That means in turn that "#ref1" is an HTML-style reference and not a new sub URL.
718 * Since HTML-style references mark
719 * a certain position in a document this reference is appended to every URL.
720 * The idea behind this is that browsers, for example, only look at the first URL while
721 * the rest is not of interest to them.
722 *
723 * @return An empty list on error or the list of split URLs.
724 *
725 * @param _url The URL that has to be split.
726 * @see #hasSubURL
727 */
728 static List split( const KURL& _url );
729
730 /**
731 * Reverses @ref #split(). Only the first URL may have a reference. This reference
732 * is considered to be HTML-like and is appended at the end of the resulting
733 * joined URL.
734 * @param _list the list to join
735 * @return the joined URL
736 */
737 static KURL join( const List& _list );
738
739 /**
740 * Creates a KURL object from a QString representing either an absolute path
741 * or a real URL. Use this method instead of
742 * <pre>
743 * QString someDir = ...
744 * KURL url = someDir;
745 * </pre>
746 *
747 * Otherwise some characters (e.g. the '#') won't be encoded properly.
748 * @param text the string representation of the URL to convert
749 * @return the new KURL
750 * @since 3.1
751 */
752 static KURL fromPathOrURL( const QString& text );
753
754/**
755 * Convenience function.
756 *
757 * Convert unicoded string to local encoding and use %-style
758 * encoding for all common delimiters / non-ascii characters.
759 * @param str String to encode (can be QString::null).
760 * @param encoding_hint MIB of encoding to use.
761 * @see QTextCodec::mibEnum()
762 * @return the encoded string
763 **/
764 static QString encode_string(const QString &str, int encoding_hint = 0);
765
766 /**
767 * Convenience function.
768 *
769 * Convert unicoded string to local encoding and use %-style
770 * encoding for all common delimiters / non-ascii characters
771 * as well as the slash '/'.
772 * @param str String to encode
773 * @param encoding_hint MIB of encoding to use.
774 * @see QTextCodec::mibEnum()
775 **/
776 static QString encode_string_no_slash(const QString &str, int encoding_hint = 0);
777
778 /**
779 * Convenience function.
780 *
781 * Decode %-style encoding and convert from local encoding to unicode.
782 *
783 * Reverse of encode_string()
784 * @param str String to decode (can be QString::null).
785 * @param encoding_hint MIB of original encoding of @p str .
786 * @see QTextCodec::mibEnum()
787 **/
788 static QString decode_string(const QString &str, int encoding_hint = 0);
789
790 /**
791 * Convenience function.
792 *
793 * Returns whether '_url' is likely to be a "relative" URL instead of
794 * an "absolute" URL.
795 * @param _url URL to examine
796 * @return true when the URL is likely to be "relative", false otherwise.
797 */
798 static bool isRelativeURL(const QString &_url);
799
800#ifdef KDE_NO_COMPAT
801private:
802#endif
803 QString filename( bool _ignore_trailing_slash_in_path = true ) const
804 {
805 return fileName(_ignore_trailing_slash_in_path);
806 }
807
808protected:
809 void reset();
810 void parse( const QString& _url, int encoding_hint = 0);
811
812private:
813 QString m_strProtocol;
814 QString m_strUser;
815 QString m_strPass;
816 QString m_strHost;
817 QString m_strPath;
818 QString m_strRef_encoded;
819 QString m_strQuery_encoded;
820 bool m_bIsMalformed : 1;
821 int freeForUse : 7;
822 unsigned short int m_iPort;
823 QString m_strPath_encoded;
824
825 friend QDataStream & operator<< (QDataStream & s, const KURL & a);
826 friend QDataStream & operator>> (QDataStream & s, KURL & a);
827private:
828 KURLPrivate* d;
829};
830
831/**
832 * Compares URLs. They are parsed, split and compared.
833 * Two malformed URLs with the same string representation
834 * are nevertheless considered to be unequal.
835 * That means no malformed URL equals anything else.
836 */
837bool urlcmp( const QString& _url1, const QString& _url2 );
838
839/**
840 * Compares URLs. They are parsed, split and compared.
841 * Two malformed URLs with the same string representation
842 * are nevertheless considered to be unequal.
843 * That means no malformed URL equals anything else.
844 *
845 * @param _ignore_trailing Described in @ref KURL::cmp
846 * @param _ignore_ref If true, disables comparison of HTML-style references.
847 */
848bool urlcmp( const QString& _url1, const QString& _url2, bool _ignore_trailing, bool _ignore_ref );
849
850QDataStream & operator<< (QDataStream & s, const KURL & a);
851QDataStream & operator>> (QDataStream & s, KURL & a);
852
853#endif
diff --git a/microkde/kutils/kcmultidialog.cpp b/microkde/kutils/kcmultidialog.cpp
new file mode 100644
index 0000000..4136622
--- a/dev/null
+++ b/microkde/kutils/kcmultidialog.cpp
@@ -0,0 +1,201 @@
1/*
2 Copyright (c) 2000 Matthias Elter <elter@kde.org>
3 Copyright (c) 2003 Daniel Molkentin <molkentin@kde.org>
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19
20*/
21
22#include <qhbox.h>
23#include <qvbox.h>
24#include <qcursor.h>
25#include <qlayout.h>
26
27#include <klocale.h>
28#include <kglobal.h>
29#include <kdebug.h>
30#include <kiconloader.h>
31#include <kmessagebox.h>
32//US #include <klibloader.h>
33#include <krun.h>
34#include <kprocess.h>
35
36#include "kcmultidialog.h"
37//US #include "kcmultidialog.moc"
38//US #include "kcmoduleloader.h"
39
40KCMultiDialog::KCMultiDialog(const QString& baseGroup, QWidget *parent, const char *name, bool modal)
41 : KDialogBase(IconList, i18n("Configure"), Default |Cancel | Apply | Ok, Ok,
42 parent, name, modal, true), d(0L)
43{
44 enableButton(Apply, false);
45 //connect(this, SIGNAL(aboutToShowPage(QWidget *)), this, SLOT(slotAboutToShow(QWidget *)));
46 _baseGroup = baseGroup;
47 mMainWidget = new KJanusWidget( this, "JanusWidget", KJanusWidget::Tabbed );
48 setMainWidget(mMainWidget );
49#ifdef DESKTOP_VERSION
50 resize(640,480);
51#else
52 resize(640,480);
53 setMaximumSize( KMIN(KGlobal::getDesktopWidth()-5, 640), KMIN(KGlobal::getDesktopHeight()-20, 480));
54 //showMaximized();
55#endif
56
57}
58
59KCMultiDialog::~KCMultiDialog()
60{
61//US moduleDict.setAutoDelete(true);
62}
63
64void KCMultiDialog::slotDefault()
65{
66
67 int curPageIndex = mMainWidget->activePageIndex();
68
69 QPtrListIterator<KCModule> it(modules);
70 for (; it.current(); ++it)
71 {
72 if (pageIndex((QWidget *)(*it)->parent()) == curPageIndex)
73 {
74 (*it)->defaults();
75 clientChanged(true);
76 return;
77 }
78 }
79
80}
81
82void KCMultiDialog::slotApply()
83{
84qDebug("KCMultiDialog::slotApply clicked");
85
86 QPtrListIterator<KCModule> it(modules);
87 for (; it.current(); ++it)
88 (*it)->save();
89 clientChanged(false);
90
91 emit applyClicked();
92
93}
94
95
96void KCMultiDialog::slotOk()
97{
98qDebug("KCMultiDialog::slotOk clicked");
99
100 QPtrListIterator<KCModule> it(modules);
101 for (; it.current(); ++it)
102 (*it)->save();
103 accept();
104
105 emit okClicked();
106}
107
108void KCMultiDialog::slotHelp()
109{
110/*US
111 KURL url( KURL("help:/"), _docPath );
112
113 if (url.protocol() == "help" || url.protocol() == "man" || url.protocol() == "info") {
114 KProcess process;
115 process << "khelpcenter"
116 << url.url();
117 process.start(KProcess::DontCare);
118 process.detach();
119 } else {
120 new KRun(url);
121 }
122*/
123}
124
125void KCMultiDialog::clientChanged(bool state)
126{
127 enableButton(Apply, state);
128}
129
130/*US
131void KCMultiDialog::addModule(const QString& path, bool withfallback)
132{
133 kdDebug(1208) << "KCMultiDialog::addModule " << path << endl;
134
135 KCModuleInfo info(path, _baseGroup);
136
137 QHBox* page = addHBoxPage(info.moduleName(), info.comment(),
138 KGlobal::iconLoader()->loadIcon(info.icon(), KIcon::Desktop, KIcon::SizeMedium));
139 if(!page) {
140 KCModuleLoader::unloadModule(info);
141 return;
142 }
143 moduleDict.insert(page, new LoadInfo(path, withfallback));
144 if (modules.isEmpty())
145 slotAboutToShow(page);
146}
147*/
148QVBox * KCMultiDialog::getNewVBoxPage( const QString & modulename )
149{
150 QVBox *page = mMainWidget->addVBoxPage(modulename , QString::null,QPixmap() );
151 return page;
152
153}
154//US special method for microkde. We dop noty want to load everything dynamically.
155void KCMultiDialog::addModule(KCModule* module ) //, const QString& modulename, const QString& iconname)
156{
157
158 modules.append(module);
159 connect(module, SIGNAL(changed(bool)), this, SLOT(clientChanged(bool)));
160
161
162}
163
164void KCMultiDialog::slotAboutToShow(QWidget *page)
165{
166/*US
167 LoadInfo *loadInfo = moduleDict[page];
168 if (!loadInfo)
169 return;
170
171 QApplication::setOverrideCursor(Qt::WaitCursor);
172
173 moduleDict.remove(page);
174
175 KCModuleInfo info(loadInfo->path, _baseGroup);
176
177 KCModule *module = KCModuleLoader::loadModule(info, loadInfo->withfallback);
178
179 if (!module)
180 {
181 QApplication::restoreOverrideCursor();
182 KCModuleLoader::showLastLoaderError(this);
183 delete loadInfo;
184 return;
185 }
186
187 module->reparent(page,0,QPoint(0,0),true);
188 connect(module, SIGNAL(changed(bool)), this, SLOT(clientChanged(bool)));
189 //setHelp( docpath, QString::null );
190 _docPath = info.docPath();
191 modules.append(module);
192
193 //KCGlobal::repairAccels( topLevelWidget() );
194
195 delete loadInfo;
196
197 QApplication::restoreOverrideCursor();
198*/
199
200qDebug("KCMultiDialog::slotAboutToShow not implemented");
201}
diff --git a/microkde/kutils/kcmultidialog.h b/microkde/kutils/kcmultidialog.h
new file mode 100644
index 0000000..63d5d42
--- a/dev/null
+++ b/microkde/kutils/kcmultidialog.h
@@ -0,0 +1,147 @@
1/*
2 Copyright (c) 2000 Matthias Elter <elter@kde.org>
3 Copyright (c) 2003 Daniel Molkentin <molkentin@kde.org>
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19
20*/
21
22#ifndef KCMULTIDIALOG_H
23#define KCMULTIDIALOG_H
24
25#include <qptrlist.h>
26#include <qptrdict.h>
27
28#include <kdialogbase.h>
29#include <kjanuswidget.h>
30#include <kcmodule.h>
31
32
33/**
34 * A class that offers a @ref KDialogBase containing arbitrary KControl Modules
35 *
36 * @short A method that offers a @ref KDialogBase containing arbitrary
37 * KControl Modules.
38 *
39 * @author Matthias Elter <elter@kde.org>, Daniel Molkentin <molkentin@kde.org>
40 * @since 3.2
41 */
42class KCMultiDialog : public KDialogBase
43{
44 Q_OBJECT
45
46public:
47 /**
48 * Constructs a new KCMultiDialog
49 *
50 * @param parent The parent Widget
51 * @param name The widget name
52 * @param baseGroup The baseGroup, if you want to call a module out of
53 * kcontrol, just keep "settings"
54 * @param modal If you pass true here, the dialog will be modal
55 **/
56 KCMultiDialog(const QString& baseGroup = QString::fromLatin1("settings"),
57 QWidget *parent=0, const char *name=0,
58 bool modal=false);
59
60 /**
61 * Destructor
62 **/
63 virtual ~KCMultiDialog();
64
65 /**
66 * Add a module.
67 *
68 * @param module Specify the name of the module that is to be added
69 * to the list of modules the dialog will show.
70 *
71 * @param withfallback Try harder to load the module. Might result
72 * in the module appearing outside the dialog.
73 **/
74//US void addModule(const QString& module, bool withfallback=true);
75
76
77//US special method for microkde. We dop noty want to load everything dynamically.
78 void addModule(KCModule* module );//, const QString& modulename, const QString& iconname);
79 QVBox* getNewVBoxPage(const QString & modulename) ;
80
81
82
83protected slots:
84 /**
85 * This slot is called when the user presses the "Default" Button
86 * You can reimplement it if needed.
87 *
88 * @note Make sure you call the original implementation!
89 **/
90 virtual void slotDefault();
91
92 /**
93 * This slot is called when the user presses the "Apply" Button
94 * You can reimplement it if needed
95 *
96 * @note Make sure you call the original implementation!
97 **/
98 virtual void slotApply();
99
100 /**
101 * This slot is called when the user presses the "OK" Button
102 * You can reimplement it if needed
103 *
104 * @note Make sure you call the original implementation!
105 **/
106 virtual void slotOk();
107
108 /**
109 * This slot is called when the user presses the "Help" Button
110 * You can reimplement it if needed
111 *
112 * @note Make sure you call the original implementation!
113 **/
114 virtual void slotHelp();
115
116private slots:
117
118 void slotAboutToShow(QWidget *);
119
120 void clientChanged(bool state);
121
122private:
123/*US
124 struct LoadInfo {
125 LoadInfo(const QString &_path, bool _withfallback)
126 : path(_path), withfallback(_withfallback)
127 { }
128 QString path;
129 bool withfallback;
130 };
131*/
132 QPtrList<KCModule> modules;
133/*
134 QPtrDict<LoadInfo> moduleDict;
135 QString _docPath;
136*/
137 QString _baseGroup;
138
139//US
140 KJanusWidget* mMainWidget;
141
142 // For future use
143 class KCMultiDialogPrivate;
144 KCMultiDialogPrivate *d;
145};
146
147#endif //KCMULTIDIALOG_H
diff --git a/microkde/microkde.pro b/microkde/microkde.pro
new file mode 100644
index 0000000..1e9b022
--- a/dev/null
+++ b/microkde/microkde.pro
@@ -0,0 +1,170 @@
1 TEMPLATE= lib
2 CONFIG += qt warn_on
3#INCLUDEPATH += $(QTDIR)/include .
4#DEPENDPATH += $(QTDIR)/include
5INCLUDEPATH += . ../ ../kabc ./kdecore ./kdeui ./kio/kfile
6#LIBS += -lqtcompat
7
8 TARGET = microkde
9DESTDIR= ../bin
10DEFINES += DESKTOP_VERSION KDE_QT_ONLY
11unix : {
12OBJECTS_DIR = obj/unix
13MOC_DIR = moc/unix
14}
15win32: {
16DEFINES += _WIN32_
17OBJECTS_DIR = obj/win
18MOC_DIR = moc/win
19}
20include( ../variables.pri )
21
22
23
24HEADERS = \
25qlayoutengine_p.h \
26KDGanttMinimizeSplitter.h \
27 kapplication.h \
28 kaudioplayer.h \
29 kcalendarsystem.h \
30 kcalendarsystemgregorian.h \
31 kcolorbutton.h \
32 kcolordialog.h \
33 kcombobox.h \
34 kconfig.h \
35 kdatetbl.h \
36 kdebug.h \
37 kdialog.h \
38 kdialogbase.h \
39 kdirwatch.h \
40 keditlistbox.h \
41 kemailsettings.h \
42 kfiledialog.h \
43 kfontdialog.h \
44 kglobal.h \
45 kglobalsettings.h \
46 kiconloader.h \
47 klineedit.h \
48 klineeditdlg.h \
49 kmessagebox.h \
50 knotifyclient.h \
51 kprinter.h \
52 kprocess.h \
53 krestrictedline.h \
54 krun.h \
55 ksimpleconfig.h \
56 kstaticdeleter.h \
57 ksystemtray.h \
58 ktempfile.h \
59 ktextedit.h \
60 kunload.h \
61 kurl.h \
62 kdeui/kguiitem.h \
63 kdeui/kcmodule.h \
64 kdeui/kbuttonbox.h \
65 kdeui/klistbox.h \
66 kdeui/klistview.h \
67 kdeui/kjanuswidget.h \
68 kdeui/kseparator.h \
69 kdeui/knuminput.h \
70 kdeui/knumvalidator.h \
71 kdeui/ksqueezedtextlabel.h \
72 kio/job.h \
73 kio/kfile/kurlrequester.h \
74 kresources/resource.h \
75 kresources/factory.h \
76 kresources/managerimpl.h \
77 kresources/manager.h \
78 kresources/selectdialog.h \
79 kresources/configpage.h \
80 kresources/configwidget.h \
81 kresources/configdialog.h \
82 kresources/kcmkresources.h \
83 kdecore/kmdcodec.h \
84 kdecore/kconfigbase.h \
85 kdecore/klocale.h \
86 kdecore/kcatalogue.h \
87 kdecore/ksharedptr.h \
88 kdecore/kshell.h \
89 kdecore/kstandarddirs.h \
90 kdecore/kstringhandler.h \
91 kdecore/kshortcut.h \
92 kutils/kcmultidialog.h \
93 kdeui/kxmlguiclient.h \
94 kdeui/kstdaction.h \
95 kdeui/kmainwindow.h \
96 kdeui/ktoolbar.h \
97 kdeui/ktoolbarbutton.h \
98 kdeui/ktoolbarhandler.h \
99 kdeui/kaction.h \
100 kdeui/kactionclasses.h \
101 kdeui/kactioncollection.h
102
103
104# kdecore/klibloader.h \
105
106
107SOURCES = \
108KDGanttMinimizeSplitter.cpp \
109 kapplication.cpp \
110 kcalendarsystem.cpp \
111 kcalendarsystemgregorian.cpp \
112 kcolorbutton.cpp \
113 kcolordialog.cpp \
114 kconfig.cpp \
115 kdatetbl.cpp \
116 kdialog.cpp \
117 kdialogbase.cpp \
118 keditlistbox.cpp \
119 kemailsettings.cpp \
120 kfontdialog.cpp \
121 kfiledialog.cpp \
122 kglobal.cpp \
123 kglobalsettings.cpp \
124 kiconloader.cpp \
125 kmessagebox.cpp \
126 ktextedit.cpp \
127 kprocess.cpp \
128 krun.cpp \
129 ksystemtray.cpp \
130 ktempfile.cpp \
131 kurl.cpp \
132 kdecore/kcatalogue.cpp \
133 kdecore/klocale.cpp \
134 kdecore/kmdcodec.cpp \
135 kdecore/kshell.cpp \
136 kdecore/kstandarddirs.cpp \
137 kdecore/kstringhandler.cpp \
138 kdeui/kbuttonbox.cpp \
139 kdeui/kcmodule.cpp \
140 kdeui/kguiitem.cpp \
141 kdeui/kjanuswidget.cpp \
142 kdeui/klistbox.cpp \
143 kdeui/klistview.cpp \
144 kdeui/knuminput.cpp \
145 kdeui/knumvalidator.cpp \
146 kdeui/kseparator.cpp \
147 kdeui/ksqueezedtextlabel.cpp \
148 kio/kfile/kurlrequester.cpp \
149 kresources/configpage.cpp \
150 kresources/configdialog.cpp \
151 kresources/configwidget.cpp \
152 kresources/factory.cpp \
153 kresources/kcmkresources.cpp \
154 kresources/managerimpl.cpp \
155 kresources/resource.cpp \
156 kresources/selectdialog.cpp \
157 kutils/kcmultidialog.cpp \
158 kdeui/kaction.cpp \
159 kdeui/kactionclasses.cpp \
160 kdeui/kactioncollection.cpp \
161 kdeui/kmainwindow.cpp \
162 kdeui/ktoolbar.cpp \
163 kdeui/ktoolbarbutton.cpp \
164 kdeui/ktoolbarhandler.cpp \
165 kdeui/kstdaction.cpp \
166 kdeui/kxmlguiclient.cpp
167
168
169
170# kdecore/klibloader.cpp \ \ No newline at end of file
diff --git a/microkde/microkde.pro.back b/microkde/microkde.pro.back
new file mode 100644
index 0000000..d2889ac
--- a/dev/null
+++ b/microkde/microkde.pro.back
@@ -0,0 +1,80 @@
1 TEMPLATE= lib
2 CONFIG = qt warn_on release
3INCLUDEPATH += $(QPEDIR)/include . ../qtcompat
4DEPENDPATH += $(QPEDIR)/include
5LIBS += -lqpe -lqtcompat
6 TARGET = microkde
7OBJECTS_DIR = obj/$(PLATFORM)
8MOC_DIR = moc
9DESTDIR=$(QPEDIR)/lib
10
11INTERFACES = \
12
13HEADERS = \
14 kapplication.h \
15 kaudioplayer.h \
16 kcalendarsystem.h \
17 kcalendarsystemgregorian.h \
18 kcolorbutton.h \
19 kcolordialog.h \
20 kcombobox.h \
21 kconfig.h \
22 kdatepicker.h \
23 kdatetbl.h \
24 kdebug.h \
25 kdialog.h \
26 kdialogbase.h \
27 kdirwatch.h \
28 keditlistbox.h \
29 kemailsettings.h \
30 kfiledialog.h \
31 kfontdialog.h \
32 kglobal.h \
33 kglobalsettings.h \
34 kiconloader.h \
35 kio/job.h \
36 klineedit.h \
37 klineeditdlg.h \
38 klistview.h \
39 klocale.h \
40 kmessagebox.h \
41 knotifyclient.h \
42 knumvalidator.h \
43 kprinter.h \
44 kprocess.h \
45 krestrictedline.h \
46 krun.h \
47 kseparator.h \
48 ksimpleconfig.h \
49 kstandarddirs.h \
50 kstaticdeleter.h \
51 ksystemtray.h \
52 ktempfile.h \
53 ktextedit.h \
54 kunload.h \
55 kurlrequester.h \
56
57SOURCES = \
58 kapplication.cpp \
59 kcalendarsystem.cpp \
60 kcalendarsystemgregorian.cpp \
61 kcolordialog.cpp \
62 kconfig.cpp \
63 kdatepicker.cpp \
64 kdatetbl.cpp \
65 kdialogbase.cpp \
66 keditlistbox.cpp \
67 kemailsettings.cpp \
68 kfontdialog.cpp \
69 kglobal.cpp \
70 kglobalsettings.cpp \
71 kiconloader.cpp \
72 klocale.cpp \
73 kmessagebox.cpp \
74 knumvalidator.cpp \
75 kprocess.cpp \
76 krun.cpp \
77 kstandarddirs.cpp \
78 ktempfile.cpp \
79 kurlrequester.cpp \
80
diff --git a/microkde/microkdeE.pro b/microkde/microkdeE.pro
new file mode 100644
index 0000000..8d04123
--- a/dev/null
+++ b/microkde/microkdeE.pro
@@ -0,0 +1,166 @@
1 TEMPLATE= lib
2CONFIG += qt warn_on
3INCLUDEPATH += . ../qtcompat ../kabc ./kdecore ./kdeui ./kio/kfile $(QPEDIR)/include
4
5DEPENDPATH += $(QPEDIR)/include
6LIBS += -lmicroqtcompat -L$(QPEDIR)/lib
7
8DEFINES += KDE_QT_ONLY
9
10 TARGET = microkde
11OBJECTS_DIR = obj/$(PLATFORM)
12MOC_DIR = moc/$(PLATFORM)
13DESTDIR=$(QPEDIR)/lib
14
15
16INTERFACES = \
17
18HEADERS = \
19qlayoutengine_p.h \
20KDGanttMinimizeSplitter.h \
21 kapplication.h \
22 kaudioplayer.h \
23 kcalendarsystem.h \
24 kcalendarsystemgregorian.h \
25 kcolorbutton.h \
26 kcolordialog.h \
27 kcombobox.h \
28 kconfig.h \
29 kdatetbl.h \
30 kdebug.h \
31 kdialog.h \
32 kdialogbase.h \
33 kdirwatch.h \
34 keditlistbox.h \
35 kemailsettings.h \
36 kfiledialog.h \
37 kfontdialog.h \
38 kglobal.h \
39 kglobalsettings.h \
40 kiconloader.h \
41 klineedit.h \
42 klineeditdlg.h \
43 kmessagebox.h \
44 knotifyclient.h \
45 kprinter.h \
46 kprocess.h \
47 krestrictedline.h \
48 krun.h \
49 ksimpleconfig.h \
50 kstaticdeleter.h \
51 ksystemtray.h \
52 ktempfile.h \
53 ktextedit.h \
54 kunload.h \
55 kurl.h \
56 ofileselector_p.h \
57 ofontselector.h \
58 kdeui/kguiitem.h \
59 kdeui/kaction.h \
60 kdeui/kactionclasses.h \
61 kdeui/kactioncollection.h \
62 kdeui/kcmodule.h \
63 kdeui/kstdaction.h \
64 kdeui/kbuttonbox.h \
65 kdeui/klistbox.h \
66 kdeui/klistview.h \
67 kdeui/kjanuswidget.h \
68 kdeui/kseparator.h \
69 kdeui/kmainwindow.h \
70 kdeui/knuminput.h \
71 kdeui/knumvalidator.h \
72 kdeui/ksqueezedtextlabel.h \
73 kdeui/ktoolbar.h \
74 kdeui/ktoolbarbutton.h \
75 kdeui/ktoolbarhandler.h \
76 kdeui/kxmlguiclient.h \
77 kio/job.h \
78 kio/kfile/kurlrequester.h \
79 kresources/resource.h \
80 kresources/factory.h \
81 kresources/managerimpl.h \
82 kresources/manager.h \
83 kresources/selectdialog.h \
84 kresources/configpage.h \
85 kresources/configwidget.h \
86 kresources/configdialog.h \
87 kresources/kcmkresources.h \
88 kdecore/kmdcodec.h \
89 kdecore/kconfigbase.h \
90 kdecore/klocale.h \
91 kdecore/klibloader.h \
92 kdecore/kcatalogue.h \
93 kdecore/ksharedptr.h \
94 kdecore/kshell.h \
95 kdecore/kstandarddirs.h \
96 kdecore/kstringhandler.h \
97 kdecore/kshortcut.h \
98 kutils/kcmultidialog.h
99
100
101
102
103SOURCES = \
104KDGanttMinimizeSplitter.cpp \
105 kapplication.cpp \
106 kcalendarsystem.cpp \
107 kcalendarsystemgregorian.cpp \
108 kcolorbutton.cpp \
109 kcolordialog.cpp \
110 kconfig.cpp \
111 kdatetbl.cpp \
112 kdialog.cpp \
113 kdialogbase.cpp \
114 keditlistbox.cpp \
115 kemailsettings.cpp \
116 kfontdialog.cpp \
117 kfiledialog.cpp \
118 kglobal.cpp \
119 kglobalsettings.cpp \
120 kiconloader.cpp \
121 kmessagebox.cpp \
122 kprocess.cpp \
123 krun.cpp \
124 ksystemtray.cpp \
125 ktempfile.cpp \
126 kurl.cpp \
127 ktextedit.cpp \
128 ofileselector_p.cpp \
129 ofontselector.cpp \
130 kdecore/kcatalogue.cpp \
131 kdecore/klibloader.cpp \
132 kdecore/klocale.cpp \
133 kdecore/kmdcodec.cpp \
134 kdecore/kshell.cpp \
135 kdecore/kstandarddirs.cpp \
136 kdecore/kstringhandler.cpp \
137 kdeui/kaction.cpp \
138 kdeui/kactionclasses.cpp \
139 kdeui/kactioncollection.cpp \
140 kdeui/kbuttonbox.cpp \
141 kdeui/kcmodule.cpp \
142 kdeui/kguiitem.cpp \
143 kdeui/kjanuswidget.cpp \
144 kdeui/klistbox.cpp \
145 kdeui/klistview.cpp \
146 kdeui/kmainwindow.cpp \
147 kdeui/knuminput.cpp \
148 kdeui/knumvalidator.cpp \
149 kdeui/kseparator.cpp \
150 kdeui/kstdaction.cpp \
151 kdeui/ksqueezedtextlabel.cpp \
152 kdeui/ktoolbar.cpp \
153 kdeui/ktoolbarbutton.cpp \
154 kdeui/ktoolbarhandler.cpp \
155 kdeui/kxmlguiclient.cpp \
156 kio/kfile/kurlrequester.cpp \
157 kresources/configpage.cpp \
158 kresources/configdialog.cpp \
159 kresources/configwidget.cpp \
160 kresources/factory.cpp \
161 kresources/kcmkresources.cpp \
162 kresources/managerimpl.cpp \
163 kresources/resource.cpp \
164 kresources/selectdialog.cpp \
165 kutils/kcmultidialog.cpp
166
diff --git a/microkde/ofileselector_p.cpp b/microkde/ofileselector_p.cpp
new file mode 100644
index 0000000..cf6074d
--- a/dev/null
+++ b/microkde/ofileselector_p.cpp
@@ -0,0 +1,863 @@
1#include <qcombobox.h>
2#include <qdir.h>
3#include <qhbox.h>
4#include <qheader.h>
5#include <qlabel.h>
6#include <qlayout.h>
7#include <qlineedit.h>
8#include <qlistview.h>
9#include <qpopupmenu.h>
10#include <qwidgetstack.h>
11#include <qregexp.h>
12#include <qobjectlist.h>
13
14/* hacky but we need to get FileSelector::filter */
15#define private public
16#include <qpe/fileselector.h>
17#undef private
18
19#include <qpe/qpeapplication.h>
20#include <qpe/mimetype.h>
21#include <qpe/resource.h>
22#include <qpe/storage.h>
23
24#include "ofileselector_p.h"
25//US#include "ofileselector.h"
26
27#include "klocale.h"
28
29OFileViewInterface::OFileViewInterface( OFileSelector* selector )
30 : m_selector( selector ) {
31}
32OFileViewInterface::~OFileViewInterface() {
33}
34QString OFileViewInterface::name()const{
35 return m_name;
36}
37void OFileViewInterface::setName( const QString& name ) {
38 m_name = name;
39}
40OFileSelector* OFileViewInterface::selector()const {
41 return m_selector;
42}
43
44DocLnk OFileViewInterface::selectedDocument()const {
45 return DocLnk( selectedName() );
46}
47
48bool OFileViewInterface::showNew()const {
49 return selector()->showNew();
50}
51bool OFileViewInterface::showClose()const {
52 return selector()->showClose();
53}
54MimeTypes OFileViewInterface::mimeTypes()const {
55 return selector()->mimeTypes();
56}
57QStringList OFileViewInterface::currentMimeType()const {
58 return selector()->currentMimeType();
59}
60void OFileViewInterface::activate( const QString& ) {
61 // not implemented here
62}
63void OFileViewInterface::ok() {
64 emit selector()->ok();
65}
66void OFileViewInterface::cancel() {
67 emit selector()->cancel();
68}
69void OFileViewInterface::closeMe() {
70 emit selector()->closeMe();
71}
72void OFileViewInterface::fileSelected( const QString& str) {
73 emit selector()->fileSelected( str);
74}
75void OFileViewInterface::fileSelected( const DocLnk& lnk) {
76 emit selector()->fileSelected( lnk );
77}
78void OFileViewInterface::setCurrentFileName( const QString& str ) {
79 selector()->m_lneEdit->setText( str );
80}
81QString OFileViewInterface::currentFileName()const{
82 return selector()->m_lneEdit->text();
83}
84QString OFileViewInterface::startDirectory()const{
85 return selector()->m_startDir;
86}
87
88
89ODocumentFileView::ODocumentFileView( OFileSelector* selector )
90 : OFileViewInterface( selector ) {
91 m_selector = 0;
92 setName( i18n("Documents") );
93}
94ODocumentFileView::~ODocumentFileView() {
95
96}
97QString ODocumentFileView::selectedName()const {
98 if (!m_selector)
99 return QString::null;
100
101 return m_selector->selected()->file();
102}
103QString ODocumentFileView::selectedPath()const {
104 return QPEApplication::documentDir();
105}
106QString ODocumentFileView::directory()const {
107 return selectedPath();
108}
109void ODocumentFileView::reread() {
110 if (!m_selector)
111 return;
112
113 m_selector->setNewVisible( showNew() );
114 m_selector->setCloseVisible( showClose() );
115 m_selector->filter = currentMimeType().join(";");
116 m_selector->reread();
117}
118int ODocumentFileView::fileCount()const {
119 if (!m_selector)
120 return -1;
121
122 return m_selector->fileCount();
123}
124
125DocLnk ODocumentFileView::selectedDocument()const {
126 if (!m_selector)
127 return DocLnk();
128 DocLnk lnk = *m_selector->selected();
129 return lnk;
130}
131
132QWidget* ODocumentFileView::widget( QWidget* parent ) {
133 if (!m_selector ) {
134 m_selector = new FileSelector(currentMimeType().join(";"), parent, "fileselector", showNew(), showClose() );
135 QObject::connect(m_selector, SIGNAL(fileSelected( const DocLnk& ) ),
136 selector(), SLOT(slotDocLnkBridge(const DocLnk&) ) );
137 QObject::connect(m_selector, SIGNAL(closeMe() ),
138 selector(), SIGNAL(closeMe() ) );
139 QObject::connect(m_selector, SIGNAL(newSelected(const DocLnk& ) ),
140 selector(), SIGNAL(newSelected(const DocLnk& ) ) );
141 }
142
143 return m_selector;
144}
145
146/*
147 * This is the file system view used
148 * we use a QListView + QListViewItems for it
149 */
150
151OFileSelectorItem::OFileSelectorItem( QListView* view, const QPixmap& pixmap,
152 const QString& path, const QString& date,
153 const QString& size, const QString& dir,
154 bool isLocked, bool isDir )
155 : QListViewItem( view )
156{
157 setPixmap(0, pixmap );
158 setText(1, path );
159 setText(2, size );
160 setText(3, date );
161 m_isDir = isDir;
162 m_dir = dir;
163 m_locked = isLocked;
164}
165OFileSelectorItem::~OFileSelectorItem() {
166
167}
168bool OFileSelectorItem::isLocked()const {
169 return m_locked;
170}
171QString OFileSelectorItem::directory()const {
172 return m_dir;
173}
174bool OFileSelectorItem::isDir()const {
175 return m_isDir;
176}
177QString OFileSelectorItem::path()const {
178 return text( 1 );
179}
180QString OFileSelectorItem::key( int id, bool )const {
181 QString ke;
182 if( id == 0 || id == 1 ){ // name
183 if( m_isDir ){
184 ke.append("0" );
185 ke.append( text(1) );
186 }else{
187 ke.append("1" );
188 ke.append( text(1) );
189 }
190 return ke;
191 }else
192 return text( id );
193
194}
195
196OFileViewFileListView::OFileViewFileListView( QWidget* parent, const QString& startDir,
197 OFileSelector* sel)
198 : QWidget( parent ), m_sel( sel ) {
199 m_all = false;
200 QVBoxLayout* lay = new QVBoxLayout( this );
201 m_currentDir = startDir;
202
203 /*
204 * now we add a special bar
205 * One Button For Up
206 * Home
207 * Doc
208 * And a dropdown menu with FileSystems
209 * FUTURE: one to change dir with lineedit
210 * Bookmarks
211 * Create Dir
212 */
213 QHBox* box = new QHBox(this );
214 box->setBackgroundMode( PaletteButton );
215 box->setSpacing( 0 );
216
217 QToolButton *btn = new QToolButton( box );
218 btn->setIconSet( Resource::loadPixmap("up") );
219 connect(btn, SIGNAL(clicked() ),
220 this, SLOT( cdUP() ) );
221
222 btn = new QToolButton( box );
223 btn->setIconSet( Resource::loadPixmap("home") );
224 connect(btn, SIGNAL(clicked() ),
225 this, SLOT( cdHome() ) );
226
227 btn = new QToolButton( box );
228 btn->setIconSet( Resource::loadPixmap("DocsIcon") );
229 connect(btn, SIGNAL(clicked() ),
230 this, SLOT(cdDoc() ) );
231
232 m_btnNew = new QToolButton( box );
233 m_btnNew->setIconSet( Resource::loadPixmap("new") );
234 connect(m_btnNew, SIGNAL(clicked() ),
235 this, SLOT(slotNew() ) );
236
237
238 m_btnClose = new QToolButton( box );
239 m_btnClose->setIconSet( Resource::loadPixmap("close") );
240 connect(m_btnClose, SIGNAL(clicked() ),
241 selector(), SIGNAL(closeMe() ) );
242
243 btn = new QToolButton( box );
244 btn->setIconSet( Resource::loadPixmap("cardmon/pcmcia") );
245
246 /* let's fill device parts */
247 QPopupMenu* pop = new QPopupMenu(this);
248 connect(pop, SIGNAL( activated(int) ),
249 this, SLOT(slotFSActivated(int) ) );
250
251 StorageInfo storage;
252 const QList<FileSystem> &fs = storage.fileSystems();
253 QListIterator<FileSystem> it(fs);
254 for ( ; it.current(); ++it ) {
255 const QString disk = (*it)->name();
256 const QString path = (*it)->path();
257 m_dev.insert( disk, path );
258 pop->insertItem( disk );
259 }
260 m_fsPop = pop;
261
262
263 btn->setPopup( pop );
264 btn->setPopupDelay ( 0 );
265 lay->addWidget( box );
266
267 m_view = new QListView( this );
268
269 m_view->installEventFilter(this);
270
271 QPEApplication::setStylusOperation( m_view->viewport(),
272 QPEApplication::RightOnHold);
273 m_view->addColumn(" " );
274 m_view->addColumn(i18n("Name"), 135 );
275 m_view->addColumn(i18n("Size"), -1 );
276 m_view->addColumn(i18n("Date"), 60 );
277 m_view->addColumn(i18n("Mime Type"), -1 );
278
279
280 m_view->setSorting( 1 );
281 m_view->setAllColumnsShowFocus( TRUE );
282
283 lay->addWidget( m_view, 1000 );
284 connectSlots();
285}
286OFileViewFileListView::~OFileViewFileListView() {
287}
288void OFileViewFileListView::slotNew() {
289 DocLnk lnk;
290 emit selector()->newSelected( lnk );
291}
292OFileSelectorItem* OFileViewFileListView::currentItem()const{
293 QListViewItem* item = m_view->currentItem();
294 if (!item )
295 return 0l;
296
297 return static_cast<OFileSelectorItem*>(item);
298}
299void OFileViewFileListView::reread( bool all ) {
300 m_view->clear();
301
302 if (selector()->showClose() )
303 m_btnClose->show();
304 else
305 m_btnClose->hide();
306
307 if (selector()->showNew() )
308 m_btnNew->show();
309 else
310 m_btnNew->hide();
311
312 m_mimes = selector()->currentMimeType();
313 m_all = all;
314
315 QDir dir( m_currentDir );
316 if (!dir.exists() )
317 return;
318 topLevelWidget()->setCaption( dir.path() );
319 dir.setSorting( QDir::Name | QDir::DirsFirst | QDir::Reversed );
320 int filter;
321 if (m_all )
322 filter = QDir::Files | QDir::Dirs | QDir::Hidden | QDir::All;
323 else
324 filter = QDir::Files | QDir::Dirs | QDir::All;
325 dir.setFilter( filter );
326
327 // now go through all files
328 const QFileInfoList *list = dir.entryInfoList();
329 if (!list) {
330 cdUP();
331 return;
332 }
333 QFileInfoListIterator it( *list );
334 QFileInfo *fi;
335 while( (fi=it.current() ) ){
336 if( fi->fileName() == QString::fromLatin1("..") || fi->fileName() == QString::fromLatin1(".") ){
337 ++it;
338 continue;
339 }
340
341 /*
342 * It is a symlink we try to resolve it now but don't let us attack by DOS
343 *
344 */
345 if( fi->isSymLink() ){
346 QString file = fi->dirPath( true ) + "/" + fi->readLink();
347 for( int i = 0; i<=4; i++) { // 5 tries to prevent dos
348 QFileInfo info( file );
349 if( !info.exists() ){
350 addSymlink( fi, TRUE );
351 break;
352 }else if( info.isDir() ){
353 addDir( fi, TRUE );
354 break;
355 }else if( info.isFile() ){
356 addFile( fi, TRUE );
357 break;
358 }else if( info.isSymLink() ){
359 file = info.dirPath(true ) + "/" + info.readLink() ;
360 break;
361 }else if( i == 4){ // couldn't resolve symlink add it as symlink
362 addSymlink( fi );
363 }
364 } // off for loop for symlink resolving
365 }else if( fi->isDir() )
366 addDir( fi );
367 else if( fi->isFile() )
368 addFile( fi );
369
370 ++it;
371 } // of while loop
372 m_view->sort();
373
374}
375int OFileViewFileListView::fileCount()const{
376 return m_view->childCount();
377}
378QString OFileViewFileListView::currentDir()const{
379 return m_currentDir;
380}
381OFileSelector* OFileViewFileListView::selector() {
382 return m_sel;
383}
384
385bool OFileViewFileListView::eventFilter (QObject *o, QEvent *e) {
386 if ( e->type() == QEvent::KeyPress ) {
387 QKeyEvent *k = (QKeyEvent *)e;
388 if ( (k->key()==Key_Enter) || (k->key()==Key_Return)) {
389 slotClicked( Qt::LeftButton,m_view->currentItem(),QPoint(0,0),0);
390 return true;
391 }
392 }
393 return false;
394}
395
396
397void OFileViewFileListView::connectSlots() {
398 connect(m_view, SIGNAL(clicked(QListViewItem*) ),
399 this, SLOT(slotCurrentChanged(QListViewItem*) ) );
400 connect(m_view, SIGNAL(mouseButtonClicked(int, QListViewItem*, const QPoint&, int ) ),
401 this, SLOT(slotClicked(int, QListViewItem*, const QPoint&, int ) ) );
402}
403void OFileViewFileListView::slotCurrentChanged( QListViewItem* item) {
404 if (!item)
405 return;
406#if 0
407
408 OFileSelectorItem *sel = static_cast<OFileSelectorItem*>(item);
409
410 if (!sel->isDir() ) {
411 selector()->m_lneEdit->setText( sel->text(1) );
412 // if in fileselector mode we will emit selected
413 if ( selector()->mode() == OFileSelector::FileSelector ) {
414 qWarning("slot Current Changed");
415 QStringList str = QStringList::split("->", sel->text(1) );
416 QString path = sel->directory() + "/" + str[0].stripWhiteSpace();
417 emit selector()->fileSelected( path );
418 DocLnk lnk( path );
419 emit selector()->fileSelected( lnk );
420 }
421 }
422#endif
423}
424void OFileViewFileListView::slotClicked(int button , QListViewItem* item, const QPoint&, int ) {
425 if (!item || ( button != Qt::LeftButton) )
426 return;
427
428 OFileSelectorItem *sel = static_cast<OFileSelectorItem*>(item);
429 if (!sel->isLocked() ) {
430 QStringList str = QStringList::split("->", sel->text(1) );
431 if (sel->isDir() ) {
432 m_currentDir = sel->directory() + "/" + str[0].stripWhiteSpace();
433 emit selector()->dirSelected( m_currentDir );
434 reread( m_all );
435 }else { // file
436 qWarning("slot Clicked");
437 selector()->m_lneEdit->setText( str[0].stripWhiteSpace() );
438 QString path = sel->directory() + "/" + str[0].stripWhiteSpace();
439 emit selector()->fileSelected( path );
440 DocLnk lnk( path );
441 emit selector()->fileSelected( lnk );
442 }
443 } // not locked
444}
445void OFileViewFileListView::addFile( QFileInfo* info, bool symlink ) {
446 MimeType type( info->absFilePath() );
447 if (!compliesMime( type.id() ) )
448 return;
449
450 QPixmap pix = type.pixmap();
451 QString dir, name; bool locked;
452 if ( pix.isNull() ) {
453 QWMatrix matrix;
454 QPixmap pixer(Resource::loadPixmap("UnknownDocument") );
455 matrix.scale( .4, .4 );
456 pix = pixer.xForm( matrix );
457 }
458 dir = info->dirPath( true );
459 locked = false;
460 if ( symlink )
461 name = info->fileName() + " -> " + info->dirPath() + "/" + info->readLink();
462 else{
463 name = info->fileName();
464 if ( ( (selector()->mode() == OFileSelector::Open)&& !info->isReadable() ) ||
465 ( (selector()->mode() == OFileSelector::Save)&& !info->isWritable() ) ) {
466 locked = true; pix = Resource::loadPixmap("locked");
467 }
468 }
469 (void)new OFileSelectorItem( m_view, pix, name,
470 info->lastModified().toString(), QString::number( info->size() ),
471 dir, locked );
472}
473void OFileViewFileListView::addDir( QFileInfo* info, bool symlink ) {
474 bool locked = false; QString name; QPixmap pix;
475
476 if ( ( ( selector()->mode() == OFileSelector::Open ) && !info->isReadable() ) ||
477 ( ( selector()->mode() == OFileSelector::Save ) && !info->isWritable() ) ) {
478 locked = true;
479 if ( symlink )
480 pix = Resource::loadPixmap( "symlink" );
481 else
482 pix = Resource::loadPixmap( "lockedfolder" );
483 }else
484 pix = symlink ? Resource::loadPixmap( "symlink") : Resource::loadPixmap("folder");
485
486 name = symlink ? info->fileName() + " -> " + info->dirPath(true) + "/" + info->readLink() :
487 info->fileName();
488
489 (void)new OFileSelectorItem( m_view, pix, name,
490 info->lastModified().toString(),
491 QString::number( info->size() ),
492 info->dirPath( true ), locked, true );
493
494
495}
496void OFileViewFileListView::addSymlink( QFileInfo* , bool ) {
497
498}
499void OFileViewFileListView::cdUP() {
500 QDir dir( m_currentDir );
501 dir.cdUp();
502
503 if (!dir.exists() )
504 m_currentDir = "/";
505 else
506 m_currentDir = dir.absPath();
507
508 emit selector()->dirSelected( m_currentDir );
509 reread( m_all );
510}
511void OFileViewFileListView::cdHome() {
512 m_currentDir = QDir::homeDirPath();
513 emit selector()->dirSelected( m_currentDir );
514 reread( m_all );
515}
516void OFileViewFileListView::cdDoc() {
517 m_currentDir = QPEApplication::documentDir();
518 emit selector()->dirSelected( m_currentDir );
519 reread( m_all );
520}
521void OFileViewFileListView::changeDir( const QString& dir ) {
522 m_currentDir = dir;
523 emit selector()->dirSelected( m_currentDir );
524 reread( m_all );
525}
526void OFileViewFileListView::slotFSActivated( int id ) {
527 changeDir ( m_dev[m_fsPop->text(id)] );
528}
529
530/* check if the mimetype in mime
531 * complies with the one which is current
532 */
533/*
534 * We've the mimetype of the file
535 * We need to get the stringlist of the current mimetype
536 *
537 * mime = image@slashjpeg
538 * QStringList = 'image@slash*'
539 * or QStringList = image/jpeg;image/png;application/x-ogg
540 * or QStringList = application/x-ogg;image@slash*;
541 * with all these mime filters it should get acceptes
542 * to do so we need to look if mime is contained inside
543 * the stringlist
544 * if it's contained return true
545 * if not ( I'm no RegExp expert at all ) we'll look if a '@slash*'
546 * is contained in the mimefilter and then we will
547 * look if both are equal until the '/'
548 */
549bool OFileViewFileListView::compliesMime( const QString& str) {
550 if (str.isEmpty() || m_mimes.isEmpty() || str.stripWhiteSpace().isEmpty() )
551 return true;
552
553 for (QStringList::Iterator it = m_mimes.begin(); it != m_mimes.end(); ++it ) {
554 QRegExp reg( (*it) );
555 reg.setWildcard( true );
556 if ( str.find( reg ) != -1 )
557 return true;
558
559 }
560 return false;
561}
562/*
563 * The listView giving access to the file system!
564 */
565class OFileViewFileSystem : public OFileViewInterface {
566public:
567 OFileViewFileSystem( OFileSelector* );
568 ~OFileViewFileSystem();
569
570 QString selectedName() const;
571 QString selectedPath() const;
572
573 QString directory()const;
574 void reread();
575 int fileCount()const;
576
577 QWidget* widget( QWidget* parent );
578 void activate( const QString& );
579private:
580 OFileViewFileListView* m_view;
581 bool m_all : 1;
582};
583OFileViewFileSystem::OFileViewFileSystem( OFileSelector* sel)
584 : OFileViewInterface( sel ) {
585 m_view = 0;
586 m_all = false;
587}
588OFileViewFileSystem::~OFileViewFileSystem() {
589}
590QString OFileViewFileSystem::selectedName()const{
591 if (!m_view )
592 return QString::null;
593
594 QString cFN=currentFileName();
595 if (cFN.startsWith("/")) return cFN;
596 return m_view->currentDir() + "/" + cFN;
597}
598QString OFileViewFileSystem::selectedPath()const{
599 return QString::null;
600}
601QString OFileViewFileSystem::directory()const{
602 if (!m_view)
603 return QString::null;
604
605 OFileSelectorItem* item = m_view->currentItem();
606 if (!item )
607 return QString::null;
608
609 return QDir(item->directory() ).absPath();
610}
611void OFileViewFileSystem::reread() {
612 if (!m_view)
613 return;
614
615 m_view->reread( m_all );
616}
617int OFileViewFileSystem::fileCount()const{
618 if (!m_view )
619 return -1;
620 return m_view->fileCount();
621}
622QWidget* OFileViewFileSystem::widget( QWidget* parent ) {
623 if (!m_view ) {
624 m_view = new OFileViewFileListView( parent, startDirectory(), selector() );
625 }
626 return m_view;
627}
628void OFileViewFileSystem::activate( const QString& str) {
629 m_all = (str !=i18n("Files") );
630
631
632}
633
634/* Selector */
635OFileSelector::OFileSelector( QWidget* parent, int mode, int sel,
636 const QString& dirName, const QString& fileName,
637 const MimeTypes& mimetypes,
638 bool showNew, bool showClose)
639 : QWidget( parent, "OFileSelector" )
640{
641 m_current = 0;
642 m_shNew = showNew;
643 m_shClose = showClose;
644 m_mimeType = mimetypes;
645 m_startDir = dirName;
646 m_mode = mode;
647 m_selector = sel;
648
649 initUI();
650 m_lneEdit->setText( fileName );
651 initMime();
652 initViews();
653
654 QString str;
655 switch ( m_selector ) {
656 default:
657 case Normal:
658 str = i18n("Documents");
659 m_cmbView->setCurrentItem( 0 );
660 break;
661 case Extended:
662 str = i18n("Files");
663 m_cmbView->setCurrentItem( 1 );
664 break;
665 case ExtendedAll:
666 str = i18n("All Files");
667 m_cmbView->setCurrentItem( 2 );
668 break;
669 }
670 slotViewChange( str );
671
672}
673OFileSelector::OFileSelector( const QString& mimeFilter, QWidget* parent, const char* name,
674 bool showNew, bool showClose )
675 : QWidget( parent, name )
676{
677 m_current = 0;
678 m_shNew = showNew;
679 m_shClose = showClose;
680 m_startDir = QPEApplication::documentDir();
681
682 if (!mimeFilter.isEmpty() )
683 m_mimeType.insert(mimeFilter, QStringList::split(";", mimeFilter ) );
684
685 m_mode = OFileSelector::FileSelector;
686 m_selector = OFileSelector::Normal;
687
688 initUI();
689 initMime();
690 initViews();
691 m_cmbView->setCurrentItem( 0 );
692 slotViewChange( i18n("Documents") );
693}
694/*
695 * INIT UI will set up the basic GUI
696 * Layout: Simple VBoxLayout
697 * On top a WidgetStack containing the Views...
698 * - List View
699 * - Document View
700 * Below we will have a Label + LineEdit
701 * Below we will have two ComoBoxes one for choosing the view one for
702 * choosing the mimetype
703 */
704void OFileSelector::initUI() {
705 QVBoxLayout* lay = new QVBoxLayout( this );
706
707 m_stack = new QWidgetStack( this );
708 lay->addWidget( m_stack, 1000 );
709
710 m_nameBox = new QHBox( this );
711 (void)new QLabel( i18n("Name:"), m_nameBox );
712 m_lneEdit = new QLineEdit( m_nameBox );
713 m_lneEdit ->installEventFilter(this);
714 lay->addWidget( m_nameBox );
715
716 m_cmbBox = new QHBox( this );
717 m_cmbView = new QComboBox( m_cmbBox );
718 m_cmbMime = new QComboBox( m_cmbBox );
719 lay->addWidget( m_cmbBox );
720}
721
722/*
723 * This will make sure that the return key in the name edit causes dialogs to close
724 */
725
726bool OFileSelector::eventFilter (QObject *o, QEvent *e) {
727 if ( e->type() == QEvent::KeyPress ) {
728 QKeyEvent *k = (QKeyEvent *)e;
729 if ( (k->key()==Key_Enter) || (k->key()==Key_Return)) {
730 emit ok();
731 return true;
732 }
733 }
734 return false;
735}
736
737/*
738 * This will insert the MimeTypes into the Combo Box
739 * And also connect the changed signal
740 *
741 * AutoMimeTyping is disabled for now. It used to reparse a dir and then set available mimetypes
742 */
743void OFileSelector::initMime() {
744 MimeTypes::Iterator it;
745 for ( it = m_mimeType.begin(); it != m_mimeType.end(); ++it ) {
746 m_cmbMime->insertItem( it.key() );
747 }
748 m_cmbMime->setCurrentItem( 0 );
749
750 connect( m_cmbMime, SIGNAL(activated(int) ),
751 this, SLOT(slotMimeTypeChanged() ) );
752
753}
754void OFileSelector::initViews() {
755 m_cmbView->insertItem( i18n("Documents") );
756 m_cmbView->insertItem( i18n("Files") );
757 m_cmbView->insertItem( i18n("All Files") );
758 connect(m_cmbView, SIGNAL(activated( const QString& ) ),
759 this, SLOT(slotViewChange( const QString& ) ) );
760
761
762 m_views.insert( i18n("Documents"), new ODocumentFileView(this) );
763
764 /* see above why add both */
765 OFileViewInterface* in = new OFileViewFileSystem( this );
766 m_views.insert( i18n("Files"), in );
767 m_views.insert( i18n("All Files"), in );
768}
769OFileSelector::~OFileSelector() {
770
771}
772
773const DocLnk* OFileSelector::selected() {
774 DocLnk* lnk = &currentView()->selectedDocument() ;
775 return lnk;
776}
777
778QString OFileSelector::selectedName()const{
779 return currentView()->selectedName();
780}
781QString OFileSelector::selectedPath()const {
782 return currentView()->selectedPath();
783}
784QString OFileSelector::directory()const {
785 return currentView()->directory();
786}
787
788DocLnk OFileSelector::selectedDocument()const {
789 return currentView()->selectedDocument();
790}
791
792int OFileSelector::fileCount()const {
793 return currentView()->fileCount();
794}
795void OFileSelector::reread() {
796 return currentView()->reread();
797}
798OFileViewInterface* OFileSelector::currentView()const{
799 return m_current;
800}
801bool OFileSelector::showNew()const {
802 return m_shNew;
803}
804bool OFileSelector::showClose()const {
805 return m_shClose;
806}
807MimeTypes OFileSelector::mimeTypes()const {
808 return m_mimeType;
809}
810int OFileSelector::mode()const{
811 return m_mode;
812}
813int OFileSelector::selector()const{
814 return m_selector;
815}
816QStringList OFileSelector::currentMimeType()const {
817 return m_mimeType[m_cmbMime->currentText()];
818}
819void OFileSelector::slotMimeTypeChanged() {
820 reread();
821}
822void OFileSelector::slotDocLnkBridge( const DocLnk& lnk) {
823 m_lneEdit->setText( lnk.name() );
824 emit fileSelected( lnk );
825 emit fileSelected( lnk.name() );
826}
827void OFileSelector::slotFileBridge( const QString& str) {
828 DocLnk lnk( str );
829 emit fileSelected( lnk );
830}
831void OFileSelector::slotViewChange( const QString& view ) {
832 OFileViewInterface* interface = m_views[view];
833 if (!interface)
834 return;
835
836 interface->activate( view );
837 if (m_current)
838 m_stack->removeWidget( m_current->widget( m_stack ) );
839
840 static int id = 1;
841
842 m_stack->addWidget( interface->widget(m_stack), id );
843 m_stack->raiseWidget( id );
844
845 interface->reread();
846 m_current = interface;
847
848 id++;
849}
850void OFileSelector::setNewVisible( bool b ) {
851 m_shNew = b;
852 currentView()->reread();
853}
854void OFileSelector::setCloseVisible( bool b ) {
855 m_shClose = b;
856 currentView()->reread();
857}
858void OFileSelector::setNameVisible( bool b ) {
859 if ( b )
860 m_nameBox->show();
861 else
862 m_nameBox->hide();
863}
diff --git a/microkde/ofileselector_p.h b/microkde/ofileselector_p.h
new file mode 100644
index 0000000..b371806
--- a/dev/null
+++ b/microkde/ofileselector_p.h
@@ -0,0 +1,258 @@
1#ifndef OPIE_OFILE_SELECTOR_PRIVATE_H
2#define OPIE_OFILE_SELECTOR_PRIVATE_H
3
4//US
5#pragma message("microkde/ofileselector_p.h")
6
7#include <qmap.h>
8#include <qstringlist.h>
9#include <qwidget.h>
10#include <qlistview.h>
11
12#include <qpe/applnk.h>
13#include <qpe/fileselector.h>
14
15
16/*
17 * How to avoid having really two different objects
18 * for Extended and ExtendedAll
19 * The only difference is the Lister...
20 * a) static object?
21 * b) leave some object inside the OFileSelector which can be used?
22 * c) when switching views tell which view we want o have.. internally we can switch then
23 *
24 * I'll take c) -zecke
25 */
26
27
28/* the View Interface */
29class OFileSelector;
30typedef QMap<QString, QStringList> MimeTypes;
31class QFileInfo;
32class QToolButton;
33class OFileViewInterface {
34public:
35 OFileViewInterface( OFileSelector* selector );
36 virtual ~OFileViewInterface();
37 virtual QString selectedName()const = 0;
38 virtual QString selectedPath()const = 0;
39 virtual QString directory()const = 0;
40 virtual void reread() = 0;
41 virtual int fileCount()const = 0;
42 virtual DocLnk selectedDocument()const;
43 virtual QWidget* widget( QWidget* parent) = 0;
44 virtual void activate( const QString& );
45 QString name()const;
46protected:
47 OFileSelector* selector()const;
48 void setName( const QString& );
49 bool showNew()const;
50 bool showClose()const;
51 MimeTypes mimeTypes()const;
52 QStringList currentMimeType()const;
53 QString startDirectory()const;
54protected:
55 void ok();
56 void cancel();
57 void closeMe();
58 void fileSelected( const QString& );
59 void fileSelected( const DocLnk& );
60 void setCurrentFileName( const QString& );
61 QString currentFileName()const;
62
63private:
64 QString m_name;
65 OFileSelector* m_selector;
66};
67
68
69/* THE Document View hosting a FileSelector*/
70class ODocumentFileView : public OFileViewInterface {
71public:
72 ODocumentFileView( OFileSelector* selector );
73 ~ODocumentFileView();
74
75 QString selectedName() const;
76 QString selectedPath() const;
77
78 QString directory() const;
79 void reread();
80 int fileCount()const;
81 DocLnk selectedDocument()const;
82
83 QWidget* widget( QWidget* parent );
84
85private:
86 mutable FileSelector* m_selector;
87
88};
89
90class OFileSelectorItem : public QListViewItem {
91public:
92 OFileSelectorItem( QListView* view, const QPixmap& pixmap,
93 const QString& path, const QString& date,
94 const QString& size, const QString& mDir,
95 bool isLocked = false, bool isDir = false );
96 ~OFileSelectorItem();
97 bool isLocked()const;
98 bool isDir()const;
99 QString directory()const;
100 QString path()const;
101 QString key(int id, bool )const;
102
103private:
104 bool m_locked : 1;
105 bool m_isDir : 1;
106 QString m_dir;
107};
108
109class OFileViewFileListView : public QWidget {
110 Q_OBJECT
111public:
112 OFileViewFileListView( QWidget* parent, const QString& dir, OFileSelector* selector );
113 ~OFileViewFileListView();
114
115 OFileSelectorItem* currentItem()const;
116 void reread( bool all = false );
117 int fileCount()const;
118 QString currentDir()const;
119protected:
120 bool eventFilter (QObject *o, QEvent *e);
121private slots:
122 void slotNew(); // will emit newSelected
123 void cdUP();
124 void cdHome();
125 void cdDoc();
126 void changeDir( const QString& );
127 void slotCurrentChanged( QListViewItem* );
128 void slotClicked(int, QListViewItem*, const QPoint&, int );
129 void slotFSActivated(int);
130
131protected:
132
133 OFileSelector* selector();
134
135private:
136 QMap<QString, QString> m_dev;
137 bool m_all : 1;
138 OFileSelector* m_sel;
139 QPopupMenu* m_fsPop;
140 bool compliesMime( const QString& );
141 QStringList m_mimes; // used in compy mime
142 QString m_currentDir;
143 QToolButton *m_btnNew, *m_btnClose;
144 void connectSlots();
145 void addFile( QFileInfo* info, bool symlink = FALSE );
146 void addDir ( QFileInfo* info, bool symlink = FALSE );
147 void addSymlink( QFileInfo* info, bool = FALSE );
148
149
150private:
151 QListView* m_view;
152};
153
154typedef QMap<QString, QStringList> MimeTypes;
155
156class OFileViewInterface;
157class OFileViewFileListView;
158class QLineEdit;
159class QComboBox;
160class QWidgetStack;
161class QHBox;
162class OFileSelector : public QWidget {
163 Q_OBJECT
164 friend class OFileViewInterface;
165 friend class OFileViewFileListView;
166public:
167 enum Mode { Open=1, Save=2, FileSelector=4, OPEN=1, SAVE=2, FILESELECTOR=4 };
168// enum OldMode { OPEN=1, SAVE=2, FILESELECTOR = 4 };
169 enum Selector { Normal = 0, Extended=1, ExtendedAll =2, Default=3, NORMAL=0,EXTENDED=1, EXTENDED_ALL =2, DEFAULT=3 };
170// enum OldSelector { NORMAL = 0, EXTENDED =1, EXTENDED_ALL = 2};
171
172 OFileSelector(QWidget* parent, int mode, int selector,
173 const QString& dirName,
174 const QString& fileName,
175 const MimeTypes& mimetypes = MimeTypes(),
176 bool newVisible = FALSE, bool closeVisible = FALSE );
177
178 OFileSelector(const QString& mimeFilter, QWidget* parent,
179 const char* name = 0, bool newVisible = TRUE, bool closeVisible = FALSE );
180 ~OFileSelector();
181
182 const DocLnk* selected();
183
184 QString selectedName()const;
185 QString selectedPath()const;
186 QString directory()const;
187
188 DocLnk selectedDocument()const;
189
190 int fileCount()const;
191 void reread();
192
193 int mode()const;
194 int selector()const;
195
196
197 void setNewVisible( bool b );
198 void setCloseVisible( bool b );
199 void setNameVisible( bool b );
200
201signals:
202 void dirSelected( const QString& );
203 void fileSelected( const DocLnk& );
204 void fileSelected( const QString& );
205 void newSelected( const DocLnk& );
206 void closeMe();
207 void ok();
208 void cancel();
209
210/* used by the ViewInterface */
211private:
212 bool showNew()const;
213 bool showClose()const;
214 MimeTypes mimeTypes()const;
215 QStringList currentMimeType()const;
216
217private:
218 /* inits the Widgets */
219 void initUI();
220 /* inits the MimeType ComboBox content + connects signals and slots */
221 void initMime();
222 /* init the Views :) */
223 void initViews();
224
225private:
226 QLineEdit* m_lneEdit; // the LineEdit for the Name
227 QComboBox *m_cmbView, *m_cmbMime; // two ComboBoxes to select the View and MimeType
228 QWidgetStack* m_stack; // our widget stack which will contain the views
229 OFileViewInterface* currentView()const; // returns the currentView
230 OFileViewInterface* m_current; // here is the view saved
231 bool m_shNew : 1; // should we show New?
232 bool m_shClose : 1; // should we show Close?
233 MimeTypes m_mimeType; // list of mimetypes
234
235 QMap<QString, OFileViewInterface*> m_views; // QString translated view name + ViewInterface Ptr
236 QHBox* m_nameBox; // the LineEdit + Label is hold here
237 QHBox* m_cmbBox; // this holds the two combo boxes
238
239 QString m_startDir;
240 int m_mode;
241 int m_selector;
242
243 struct Data; // used for future versions
244 Data *d;
245
246private slots:
247 void slotMimeTypeChanged();
248
249 /* will set the text of the lineedit and emit a fileChanged signal */
250 void slotDocLnkBridge( const DocLnk& );
251 void slotFileBridge( const QString& );
252 void slotViewChange( const QString& );
253
254 bool eventFilter (QObject *o, QEvent *e);
255
256};
257
258#endif
diff --git a/microkde/ofontselector.cpp b/microkde/ofontselector.cpp
new file mode 100644
index 0000000..c8471cc
--- a/dev/null
+++ b/microkde/ofontselector.cpp
@@ -0,0 +1,412 @@
1/*
2               =. This file is part of the OPIE Project
3             .=l. Copyright (c) 2002 Robert Griebl <sandman@handhelds.org>
4           .>+-=
5 _;:,     .>    :=|. This library is free software; you can
6.> <`_,   >  .   <= redistribute it and/or modify it under
7:`=1 )Y*s>-.--   : the terms of the GNU Library General Public
8.="- .-=="i,     .._ License as published by the Free Software
9 - .   .-<_>     .<> Foundation; either version 2 of the License,
10     ._= =}       : or (at your option) any later version.
11    .%`+i>       _;_.
12    .i_,=:_.      -<s. This library is distributed in the hope that
13     +  .  -:.       = it will be useful, but WITHOUT ANY WARRANTY;
14    : ..    .:,     . . . without even the implied warranty of
15    =_        +     =;=|` MERCHANTABILITY or FITNESS FOR A
16  _.=:.       :    :=>`: PARTICULAR PURPOSE. See the GNU
17..}^=.=       =       ; Library General Public License for more
18++=   -.     .`     .: details.
19 :     =  ...= . :.=-
20 -.   .:....=;==+<; You should have received a copy of the GNU
21  -_. . .   )=.  = Library General Public License along with
22    --        :-=` this library; see the file COPYING.LIB.
23 If not, write to the Free Software Foundation,
24 Inc., 59 Temple Place - Suite 330,
25 Boston, MA 02111-1307, USA.
26
27*/
28
29#include <qlayout.h>
30#include <qlistbox.h>
31#include <qcombobox.h>
32#include <qlabel.h>
33#include <qfont.h>
34#include <qmultilineedit.h>
35
36#include <qpe/fontdatabase.h>
37
38#include "ofontselector.h"
39
40class OFontSelectorPrivate {
41public:
42 QListBox * m_font_family_list;
43 QComboBox * m_font_style_list;
44 QComboBox * m_font_size_list;
45 QMultiLineEdit *m_preview;
46
47 bool m_pointbug : 1;
48
49 FontDatabase m_fdb;
50};
51
52namespace {
53
54class FontListItem : public QListBoxText {
55public:
56 FontListItem ( const QString &t, const QStringList &styles, const QValueList<int> &sizes ) : QListBoxText ( )
57 {
58 m_name = t;
59 m_styles = styles;
60 m_sizes = sizes;
61
62 QString str = t;
63 str [0] = str [0]. upper ( );
64 setText ( str );
65 }
66
67 QString family ( ) const
68 {
69 return m_name;
70 }
71
72 const QStringList &styles ( ) const
73 {
74 return m_styles;
75 }
76
77 const QValueList<int> &sizes ( ) const
78 {
79 return m_sizes;
80 }
81
82private:
83 QStringList m_styles;
84 QValueList<int> m_sizes;
85 QString m_name;
86};
87
88
89static int findItemCB ( QComboBox *box, const QString &str )
90{
91 for ( int i = 0; i < box-> count ( ); i++ ) {
92 if ( box-> text ( i ) == str )
93 return i;
94 }
95 return -1;
96}
97
98}
99/* static same as anon. namespace */
100static int qt_version ( )
101{
102 const char *qver = qVersion ( );
103
104 return ( qver [0] - '0' ) * 100 + ( qver [2] - '0' ) * 10 + ( qver [4] - '0' );
105}
106
107/**
108 * Constructs the Selector object
109 * @param withpreview If a font preview should be given
110 * @param parent The parent of the Font Selector
111 * @param name The name of the object
112 * @param fl WidgetFlags
113 */
114OFontSelector::OFontSelector ( bool withpreview, QWidget *parent, const char *name, WFlags fl ) : QWidget ( parent, name, fl )
115{
116 d = new OFontSelectorPrivate ( );
117
118 QGridLayout *gridLayout = new QGridLayout ( this, 0, 0, 4, 4 );
119 gridLayout->setRowStretch ( 4, 10 );
120
121 d-> m_font_family_list = new QListBox( this, "FontListBox" );
122 gridLayout->addMultiCellWidget( d-> m_font_family_list, 0, 4, 0, 0 );
123 connect( d-> m_font_family_list, SIGNAL( highlighted( int ) ), this, SLOT( fontFamilyClicked( int ) ) );
124
125 QLabel *label = new QLabel( tr( "Style" ), this );
126 gridLayout->addWidget( label, 0, 1 );
127
128 d-> m_font_style_list = new QComboBox( this, "StyleListBox" );
129 connect( d-> m_font_style_list, SIGNAL( activated( int ) ), this, SLOT( fontStyleClicked( int ) ) );
130 gridLayout->addWidget( d-> m_font_style_list, 1, 1 );
131
132 label = new QLabel( tr( "Size" ), this );
133 gridLayout->addWidget( label, 2, 1 );
134
135 d-> m_font_size_list = new QComboBox( this, "SizeListBox" );
136 connect( d-> m_font_size_list, SIGNAL( activated( int ) ),
137 this, SLOT( fontSizeClicked( int ) ) );
138 gridLayout->addWidget( d-> m_font_size_list, 3, 1 );
139
140 d-> m_pointbug = ( qt_version ( ) <= 233 );
141
142 if ( withpreview ) {
143 d-> m_preview = new QMultiLineEdit ( this, "Preview" );
144 d-> m_preview-> setAlignment ( AlignCenter );
145 d-> m_preview-> setWordWrap ( QMultiLineEdit::WidgetWidth );
146 d-> m_preview-> setMargin ( 3 );
147 d-> m_preview-> setText ( tr( "The Quick Brown Fox Jumps Over The Lazy Dog" ));
148 gridLayout-> addRowSpacing ( 5, 4 );
149 gridLayout-> addMultiCellWidget ( d-> m_preview, 6, 6, 0, 1 );
150 gridLayout-> setRowStretch ( 6, 5 );
151 }
152 else
153 d-> m_preview = 0;
154
155 loadFonts ( d-> m_font_family_list );
156}
157
158OFontSelector::~OFontSelector ( )
159{
160 delete d;
161}
162
163/**
164 * This methods tries to set the font
165 * @param f The wishes font
166 * @return success or failure
167 */
168bool OFontSelector::setSelectedFont ( const QFont &f )
169{
170 return setSelectedFont ( f. family ( ), d-> m_fdb. styleString ( f ), f. pointSize ( ), QFont::encodingName ( f. charSet ( )));
171}
172
173
174/**
175 * This is an overloaded method @see setSelectedFont
176 * @param familyStr The family of the font
177 * @param styleStr The style of the font
178 * @param sizeVal The size of font
179 * @param charset The charset to be used. Will be deprecated by QT3
180 */
181bool OFontSelector::setSelectedFont ( const QString &familyStr, const QString &styleStr, int sizeVal, const QString & charset )
182{
183 QString sizeStr = QString::number ( sizeVal );
184
185 QListBoxItem *family = d-> m_font_family_list-> findItem ( familyStr );
186 if ( !family )
187 family = d-> m_font_family_list-> findItem ( "Helvetica" );
188 if ( !family )
189 family = d-> m_font_family_list-> firstItem ( );
190 d-> m_font_family_list-> setCurrentItem ( family );
191 fontFamilyClicked ( d-> m_font_family_list-> index ( family ));
192
193 int style = findItemCB ( d-> m_font_style_list, styleStr );
194 if ( style < 0 )
195 style = findItemCB ( d-> m_font_style_list, "Regular" );
196 if ( style < 0 && d-> m_font_style_list-> count ( ) > 0 )
197 style = 0;
198 d-> m_font_style_list-> setCurrentItem ( style );
199 fontStyleClicked ( style );
200
201 int size = findItemCB ( d-> m_font_size_list, sizeStr );
202 if ( size < 0 )
203 size = findItemCB ( d-> m_font_size_list, "10" );
204 if ( size < 0 && d-> m_font_size_list-> count ( ) > 0 )
205 size = 0;
206 d-> m_font_size_list-> setCurrentItem ( size );
207 fontSizeClicked ( size );
208
209 return (( family ) && ( style >= 0 ) && ( size >= 0 ));
210}
211
212/**
213 * This method returns the name, style and size of the currently selected
214 * font or false if no font is selected
215 * @param family The font family will be written there
216 * @param style The style will be written there
217 * @param size The size will be written there
218 * @return success or failure
219 */
220bool OFontSelector::selectedFont ( QString &family, QString &style, int &size )
221{
222 QString dummy;
223 return selectedFont ( family, style, size, dummy );
224}
225
226
227/**
228 * This method does return the font family or QString::null if there is
229 * no font item selected
230 * @return the font family
231 */
232QString OFontSelector::fontFamily ( ) const
233{
234 FontListItem *fli = (FontListItem *) d-> m_font_family_list-> item ( d-> m_font_family_list-> currentItem ( ));
235
236 return fli ? fli-> family ( ) : QString::null;
237}
238
239/**
240 * This method will return the style of the font or QString::null
241 * @return the style of the font
242 */
243QString OFontSelector::fontStyle ( ) const
244{
245 FontListItem *fli = (FontListItem *) d-> m_font_family_list-> item ( d-> m_font_family_list-> currentItem ( ));
246 int fst = d-> m_font_style_list-> currentItem ( );
247
248 return ( fli && fst >= 0 ) ? fli-> styles ( ) [fst] : QString::null;
249}
250
251/**
252 * This method will return the font size or 10 if no font size is available
253 */
254int OFontSelector::fontSize ( ) const
255{
256 FontListItem *fli = (FontListItem *) d-> m_font_family_list-> item ( d-> m_font_family_list-> currentItem ( ));
257 int fsi = d-> m_font_size_list-> currentItem ( );
258
259 return ( fli && fsi >= 0 ) ? fli-> sizes ( ) [fsi] : 10;
260}
261
262/**
263 * returns the charset of the font or QString::null
264 */
265QString OFontSelector::fontCharSet ( ) const
266{
267 FontListItem *fli = (FontListItem *) d-> m_font_family_list-> item ( d-> m_font_family_list-> currentItem ( ));
268
269 return fli ? d-> m_fdb. charSets ( fli-> family ( )) [0] : QString::null;
270}
271
272/**
273 * Overloaded member function see above
274 * @see selectedFont
275 */
276bool OFontSelector::selectedFont ( QString &family, QString &style, int &size, QString &charset )
277{
278 int ffa = d-> m_font_family_list-> currentItem ( );
279 int fst = d-> m_font_style_list-> currentItem ( );
280 int fsi = d-> m_font_size_list-> currentItem ( );
281
282 FontListItem *fli = (FontListItem *) d-> m_font_family_list-> item ( ffa );
283
284 if ( fli ) {
285 family = fli-> family ( );
286 style = fst >= 0 ? fli-> styles ( ) [fst] : QString::null;
287 size = fsi >= 0 ? fli-> sizes ( ) [fsi] : 10;
288 charset = d-> m_fdb. charSets ( fli-> family ( )) [0];
289
290 return true;
291 }
292 else
293 return false;
294}
295
296
297
298
299void OFontSelector::loadFonts ( QListBox *list )
300{
301 QStringList f = d-> m_fdb. families ( );
302
303 for ( QStringList::ConstIterator it = f. begin ( ); it != f. end ( ); ++it ) {
304 QValueList <int> ps = d-> m_fdb. pointSizes ( *it );
305
306 if ( d-> m_pointbug ) {
307 for ( QValueList <int>::Iterator it = ps. begin ( ); it != ps. end ( ); it++ )
308 *it /= 10;
309 }
310
311 list-> insertItem ( new FontListItem ( *it, d-> m_fdb. styles ( *it ), ps ));
312 }
313}
314
315void OFontSelector::fontFamilyClicked ( int index )
316{
317 QString oldstyle = d-> m_font_style_list-> currentText ( );
318 QString oldsize = d-> m_font_size_list-> currentText ( );
319
320 FontListItem *fli = (FontListItem *) d-> m_font_family_list-> item ( index );
321
322 d-> m_font_style_list-> clear ( );
323 d-> m_font_style_list-> insertStringList ( fli-> styles ( ));
324 d-> m_font_style_list-> setEnabled ( !fli-> styles ( ). isEmpty ( ));
325
326 int i;
327
328 i = findItemCB ( d-> m_font_style_list, oldstyle );
329 if ( i < 0 )
330 i = findItemCB ( d-> m_font_style_list, "Regular" );
331 if (( i < 0 ) && ( d-> m_font_style_list-> count ( ) > 0 ))
332 i = 0;
333
334 if ( i >= 0 ) {
335 d-> m_font_style_list-> setCurrentItem ( i );
336 fontStyleClicked ( i );
337 }
338
339 d-> m_font_size_list-> clear ( );
340 QValueList<int> sl = fli-> sizes ( );
341
342 for ( QValueList<int>::Iterator it = sl. begin ( ); it != sl. end ( ); ++it )
343 d-> m_font_size_list-> insertItem ( QString::number ( *it ));
344
345 i = findItemCB ( d-> m_font_size_list, oldsize );
346 if ( i < 0 )
347 i = findItemCB ( d-> m_font_size_list, "10" );
348 if (( i < 0 ) && ( d-> m_font_size_list-> count ( ) > 0 ))
349 i = 0;
350
351 if ( i >= 0 ) {
352 d-> m_font_size_list-> setCurrentItem ( i );
353 fontSizeClicked ( i );
354 }
355 changeFont ( );
356}
357
358void OFontSelector::fontStyleClicked ( int /*index*/ )
359{
360 changeFont ( );
361}
362
363void OFontSelector::fontSizeClicked ( int /*index*/ )
364{
365 changeFont ( );
366}
367
368void OFontSelector::changeFont ( )
369{
370 QFont f = selectedFont ( );
371
372 if ( d-> m_preview )
373 d-> m_preview-> setFont ( f );
374
375 emit fontSelected ( f );
376}
377
378/**
379 * Return the selected font
380 */
381QFont OFontSelector::selectedFont ( )
382{
383 int ffa = d-> m_font_family_list-> currentItem ( );
384 int fst = d-> m_font_style_list-> currentItem ( );
385 int fsi = d-> m_font_size_list-> currentItem ( );
386
387 FontListItem *fli = (FontListItem *) d-> m_font_family_list-> item ( ffa );
388
389 if ( fli ) {
390 return d-> m_fdb. font ( fli-> family ( ), \
391 fst >= 0 ? fli-> styles ( ) [fst] : QString::null, \
392 fsi >= 0 ? fli-> sizes ( ) [fsi] : 10, \
393 d-> m_fdb. charSets ( fli-> family ( )) [0] );
394 }
395 else
396 return QFont ( );
397}
398
399
400void OFontSelector::resizeEvent ( QResizeEvent *re )
401{
402 if ( d-> m_preview ) {
403 d-> m_preview-> setMinimumHeight ( 1 );
404 d-> m_preview-> setMaximumHeight ( 32767 );
405 }
406
407 QWidget::resizeEvent ( re );
408
409 if ( d-> m_preview )
410 d-> m_preview-> setFixedHeight ( d-> m_preview-> height ( ));
411
412}
diff --git a/microkde/ofontselector.h b/microkde/ofontselector.h
new file mode 100644
index 0000000..b819c45
--- a/dev/null
+++ b/microkde/ofontselector.h
@@ -0,0 +1,96 @@
1/*
2               =. This file is part of the OPIE Project
3             .=l. Copyright (c) 2002 Robert Griebl <sandman@handhelds.org>
4           .>+-=
5 _;:,     .>    :=|. This library is free software; you can
6.> <`_,   >  .   <= redistribute it and/or modify it under
7:`=1 )Y*s>-.--   : the terms of the GNU Library General Public
8.="- .-=="i,     .._ License as published by the Free Software
9 - .   .-<_>     .<> Foundation; either version 2 of the License,
10     ._= =}       : or (at your option) any later version.
11    .%`+i>       _;_.
12    .i_,=:_.      -<s. This library is distributed in the hope that
13     +  .  -:.       = it will be useful, but WITHOUT ANY WARRANTY;
14    : ..    .:,     . . . without even the implied warranty of
15    =_        +     =;=|` MERCHANTABILITY or FITNESS FOR A
16  _.=:.       :    :=>`: PARTICULAR PURPOSE. See the GNU
17..}^=.=       =       ; Library General Public License for more
18++=   -.     .`     .: details.
19 :     =  ...= . :.=-
20 -.   .:....=;==+<; You should have received a copy of the GNU
21  -_. . .   )=.  = Library General Public License along with
22    --        :-=` this library; see the file COPYING.LIB.
23 If not, write to the Free Software Foundation,
24 Inc., 59 Temple Place - Suite 330,
25 Boston, MA 02111-1307, USA.
26
27*/
28
29#ifndef OPIE_FONTSELECTOR_H__
30#define OPIE_FONTSELECTOR_H__
31
32#include <qwidget.h>
33
34class QListBox;
35class OFontSelectorPrivate;
36
37/**
38 * This class lets you chose a Font out of a list of Fonts.
39 * It can show a preview too. This selector will use all available
40 * fonts
41 *
42 *
43 * @short A widget to select a font
44 * @see QWidget
45 * @see QFont
46 * @author Rober Griebl
47 */
48class OFontSelector : public QWidget
49{
50 Q_OBJECT
51
52public:
53 OFontSelector ( bool withpreview, QWidget* parent = 0, const char* name = 0, WFlags fl = 0 );
54 virtual ~OFontSelector ( );
55
56 bool selectedFont ( QString &family, QString &style, int &size );
57 bool selectedFont ( QString &family, QString &style, int &size, QString &charset );
58
59 QFont selectedFont ( );
60
61 bool setSelectedFont ( const QFont & );
62 bool setSelectedFont ( const QString &family, const QString &style, int size, const QString &charset = 0 );
63
64 QString fontFamily ( ) const;
65 QString fontStyle ( ) const;
66 int fontSize ( ) const;
67 QString fontCharSet ( ) const;
68
69signals:
70 /**
71 * This signal gets emitted when a font got chosen
72 */
73 void fontSelected ( const QFont & );
74
75protected slots:
76 /** @internal */
77 virtual void fontFamilyClicked ( int );
78 /** @internal */
79 virtual void fontStyleClicked ( int );
80 /** @internal */
81 virtual void fontSizeClicked ( int );
82
83protected:
84 virtual void resizeEvent ( QResizeEvent *re );
85
86private:
87 void loadFonts ( QListBox * );
88
89 void changeFont ( );
90
91private:
92 OFontSelectorPrivate *d;
93};
94
95#endif
96
diff --git a/microkde/qlayoutengine_p.h b/microkde/qlayoutengine_p.h
new file mode 100644
index 0000000..2d6a556
--- a/dev/null
+++ b/microkde/qlayoutengine_p.h
@@ -0,0 +1,111 @@
1// THIS IS A COPY OF THE FILE FOUND IN $QTDIR/src/kernel. Needed to modify qsplitter
2
3/****************************************************************************
4** $Id$
5**
6** Internal header file.
7**
8** Created : 981027
9**
10** Copyright (C) 1998-99 by Trolltech AS. All rights reserved.
11**
12** This file is part of the kernel module of the Qt GUI Toolkit.
13**
14** This file may be distributed under the terms of the Q Public License
15** as defined by Trolltech AS of Norway and appearing in the file
16** LICENSE.QPL included in the packaging of this file.
17**
18** This file may be distributed and/or modified under the terms of the
19** GNU General Public License version 2 as published by the Free Software
20** Foundation and appearing in the file LICENSE.GPL included in the
21** packaging of this file.
22**
23** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
24** licenses may use this file in accordance with the Qt Commercial License
25** Agreement provided with the Software.
26**
27** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
28** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
29**
30** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
31** information about Qt Commercial License Agreements.
32** See http://www.trolltech.com/qpl/ for QPL licensing information.
33** See http://www.trolltech.com/gpl/ for GPL licensing information.
34**
35** Contact info@trolltech.com if any conditions of this licensing are
36** not clear to you.
37**
38**********************************************************************/
39
40#ifndef QLAYOUTENGINE_P_H
41#define QLAYOUTENGINE_P_H
42
43
44//
45// W A R N I N G
46// -------------
47//
48// This file is not part of the Qt API. It exists for the convenience
49// of qlayout.cpp, qlayoutengine.cpp, qmainwindow.cpp and qsplitter.cpp.
50// This header file may change from version to version without notice,
51// or even be removed.
52//
53// We mean it.
54//
55//
56
57
58#ifndef QT_H
59#include "qabstractlayout.h"
60#endif // QT_H
61
62#ifndef QT_NO_LAYOUT
63struct QLayoutStruct
64{
65 void initParameters() { minimumSize = sizeHint = 0;
66 maximumSize = QWIDGETSIZE_MAX; expansive = FALSE; empty = TRUE; }
67 void init() { stretch = 0; initParameters(); }
68 //permanent storage:
69 int stretch;
70 //parameters:
71 QCOORD sizeHint;
72 QCOORD maximumSize;
73 QCOORD minimumSize;
74 bool expansive;
75 bool empty;
76 //temporary storage:
77 bool done;
78 //result:
79 int pos;
80 int size;
81};
82
83
84void qGeomCalc( QMemArray<QLayoutStruct> &chain, int start, int count, int pos,
85 int space, int spacer );
86
87
88
89/*
90 Modify total maximum (max) and total expansion (exp)
91 when adding boxmax/boxexp.
92
93 Expansive boxes win over non-expansive boxes.
94*/
95static inline void qMaxExpCalc( QCOORD & max, bool &exp,
96 QCOORD boxmax, bool boxexp )
97{
98 if ( exp ) {
99 if ( boxexp )
100 max = QMAX( max, boxmax );
101 } else {
102 if ( boxexp )
103 max = boxmax;
104 else
105 max = QMIN( max, boxmax );
106 }
107 exp = exp || boxexp;
108}
109
110#endif //QT_NO_LAYOUT
111#endif
diff --git a/microkde/words.sort.txt b/microkde/words.sort.txt
new file mode 100644
index 0000000..a477be7
--- a/dev/null
+++ b/microkde/words.sort.txt
@@ -0,0 +1,549 @@
1
2{ "10 minutes", "10 Minuten", },
3{ "10th", "10." },
4{ "11th", "11." },
5{ "12 pm Format", "12 AM/PM Format" },
6{ "12th", "12." },
7{ "13th", "13." },
8{ "14th", "14." },
9{ "15th", "15." },
10{ "16th", "16." },
11{ "17th", "17." },
12{ "18th", "18." },
13{ "19th", "19." },
14{ "1 Day", "1 Tag" },
15{ "1 h", "1 Std" },
16{ "1 (Highest)", "1 (Höchster)" },
17{ "1st", "1." },
18{ "1st", "2." },
19{ "20th", "20." },
20{ "21st", "21." },
21{ "22nd", "22." },
22{ "23rd", "23." },
23{ "24:00 Hour Format", "24:00 Stunden Format" },
24{ "24th", "24." },
25{ "25th", "25." },
26{ "26th", "26." },
27{ "27th", "27." },
28{ "28th", "28." },
29{ "29th", "29." },
30{ "2nd", "2." },
31{ "30 minutes", "30 Minuten" },
32{ "30th", "30." },
33{ "31st", "31." },
34{ "3rd", "3." },
35{ "4th", "4." },
36{ "5 (lowest)", "5 (Niedrigster)" },
37{ "5th", "5." },
38{ "6th", "6." },
39{ "7th", "7." },
40{ "8th", "8." },
41{ "9th", "9." },
42{ "&Accept", "&Akzeptieren" },
43{ "Accept", "Akzeptieren" },
44{ "Accept A&ll", "A&lles Akzepieren" },
45{ "Access:", "Zugriff:" },
46{ "A corresponding event is missing in your calendar!", "Ein zugehöriges Ereignis fehlt in ihrem Kalender!" },
47{ "Actions", "Aktionen" },
48{ "Add Filter", "Filter Hinzufügen" },
49{ "&Add", "Hinzufügen" },
50{ "Add", "Hinzufügen" },
51{ "Additional email addresses:", "Zusätzliche E-Mail Adressen:" },
52{ "Additional email address:", "Zusätzliche E-Mail Adresse:" },
53{ "&Addressbook", "&Adressbuch" },
54{ "Address &Book...", "Adress&buch..." },
55{ "Agenda Size", "Agende Größe" },
56{ "Agenda Size:", "Größe der Agenda:" },
57{ "Agenda view:", "Agenda Anzeige:" },
58{ "Agenda view background color:", "Hintergrundfarbe der Agenda Anzeige:" },
59{ "All attendees", "Alle Teilnehmer" },
60{ "AllDayAgenda Height:", "Ganztagesagenda Höhe" },
61{ "Allday", "Ganztägig" },
62{ "Anonymous", "Anonym" },
63{ "Apply", "Bestätigen" },
64//{ "Appointment Time ", "" },
65{ "Apr", "Apr" },
66{ "April", "April" },
67//"Ask for every entry on conflict", "",
68{ "Ask for preferences before syncing", "Vor dem Syncronisieren nachfragen" },
69{ "Ask for quit when closing KO/Pi", "Vor dem Beenden von KO/Pi nachfragen" },
70{ "Attendees", "Teilnehmer" },
71{ "Aug", "Aug" },
72{ "August", "August" },
73//"Auto Insert IMIP Replies"),
74//"Auto Insert IMIP Requests"),
75{ "Auto-Save", "Automatisches Abspeichern" },
76{ "Auto save delay in minutes:", "Auto Save Intervall in Minuten" },
77//"Auto Save FreeBusy Replies", ""
78//"Auto Send FreeBusy Information"),
79//"Auto Send Refresh"),
80//"<b>Due on:</b> %1", "",
81//"be added to the standard resource", "",
82//"be asked which resource to use", "",
83{ "Begin on:", "Starte mit:" },
84{ "Begins on: %1", "Starte mit: %1" },
85{ "<b>From:</b> %1 <b>To:</b> %2", "<b>Vom:</b> %1 <b>Zum:</b> %2" },
86{ "Bigger", "Größer" },
87{ "Biggest", "Am größten" },
88{ "Big", "Groß" },
89{ "<b>On:</b> %1", "<b>Am:</b> %1" },
90{ "<b>On:</b> %1 <b>From:S</b> %2 <b>To:</b> %3", "<b>Am:</b> %1 <b>Vom:S</b> %2 <b>Zum:</b> %3" },
91{ "<b>Original event:</b><p>", "<b>Original Ereignis:</b><p>" },
92{ " - both are modified after last sync", " - beide wurden nach der letzten Syncronisation verändert" },
93{ "Busy", "Belegt" },
94{ "&Cancel", "Abbre&chen" },
95{ "Cancel", "Abbrechen" },
96{ "Cannot delete To-Do\nwhich has children.", "Kann Todo nicht löschen,\n da noch Einträge vorhanden sind" },
97{ "Cannot delete To-Do which has children.", "Kann Todo nicht löschen, da noch Einträge vorhanden sind" },
98//"Cannot move To-Do to itself or a child of itself"),
99//"Cannot purge To-Do which\nhas uncompleted children."
100//"Can't generate mail:\nNo attendees defined.\n"));
101{ "Can't generate mail:\nNo event selected.", "Kann e-Mail nicht erstellen:\nKein Ereignis ausgewählt." },
102{ "Categories...", "Kategorien..." },
103{ "Categories", "Kategorien" },
104{ "Category", "Kategorie" },
105{ "Center View", "Mittenansicht" },
106{ "Change", "Verändere" },
107{ "Cinema", "Kino" },
108{ "Click to add a new Todo", "Klicken, um ein neues Todo anzulegen" },
109{ "Clone Item", "Klone Eintrag" },
110{ "&Close", "S&chließen" },
111{ "Close", "Schließen" },
112{ "Close this dialog to abort deletion!", "Zum Abbrechen des Löschvorganges Dialog schließen!" },
113{ "Colors", "Farben" },
114{ "completed", "fertiggestellt" },
115{ "completed on %1", "fertiggestellt um %1" },
116{ "Complete", "Fertigstellen" },
117//{ "concatenation of dates and time", "%1 %2" },
118{ "Confirm &deletes", "Löschvogang bestätigen" },
119//"Copying succeed. Syncing not yet implemented"
120//"Copy remote file to local machine..."
121//{ "Could not find your attendee entry.\nPlease check the emails.")) },
122{ "Couldn't load calendar\n '%1'.", "Kann Kalender\n '%1' nicht laden." },
123{ "Counter-event Viewer", "Ereigniszähler Anzeige" },
124//{ "counter proposal event","<b>Counter-event:</b><p>" },
125{ "Daily ending hour:", "Tägl. Schlusszeit:" },
126{ "Daily starting hour:", "Tägliche Anfangszeit:" },
127{ "Daily", "Täglich" },
128{ "Date Format", "Datum Format" },
129{ "DateNavigator:(nr)" , "Datums Navigator" },
130//{ "Date Range") },
131{ "Dates: ", "Datum: " },
132{ "Date && Time", "Datum && Zeit" },
133{ "Day begins at:", "Der Tag beginnt um:" },
134{ "Days in Next-X-Days:", "Tage in den Nächsten-X-Tagen:" },
135{ "Days in What's Next:", "Tage in Was-kommt-Nun:" },
136{ "day(s)", "Tag(e)" },
137{ "Days to show in Next-X-Days view:", "Welche Tage in Nächste-X-Tagen anzeigen:" },
138{ "day", "Tag" },
139{ "Dec", "Dez" },
140{ "December", "Dezember" },
141{ "Default alarm time:", "Standard Alarm Zeit:" },
142//{ "Default appointment time:") },
143//{ "Default Calendar Format") },
144//{ "Default event color:") },
145//{ "Default export file", "calendar.html")) },
146{ "Default", "Standard" },
147//{ "Def. duration of new app.:") },
148{ "Delete All", "Lösche alles" },
149{ "Delete all selected", "Lösche alle ausgewählten" },
150//{ "delete completed To-Dos","Purge Completed") },
151//{ "delete completed To-Dos","Purge Completed") },
152{ "Delete Current", "Aktuellen löschen" },
153{ "Delete Event...", "Lösche Ereignis..." },
154{ "Delete Event", "Lösche Ereignis" },
155{ "&Delete", "Löschen" },
156{ "Delete", "Löschen" },
157{ "Delete Todo...", "Lösche Todo..." },
158{ "Delete To-Do", "Lösche Todo" },
159{ "Deleting item %d ...", "Lösche Eintrag %d..." },
160{ "Descriptions", "Beschreibungen" },
161{ "Deselect All", "Alles deselektieren" },
162{ "Details", "Details" },
163{ "Dinner", "Abendessen" },
164//{ "%d item(s) found."), mMatchedEvents.count() ) },
165//{ "%d items remaining in list."), count() ) },
166{ "Do you really want\nto close KO/Pi?", "Möchten Sie wirklich\nKO/PI verlassen?" },
167//"Do you really want\nto remote sync?\n \n"
168//{ "Drop Event },
169//{ "Drop To-Do")) },
170//{ "Due Date")) },
171//{ "Due: ")+ (static_cast<Todo*>(mIncidence))->dtDueTimeStr() },
172//{ "Due Time")) },
173//{ "Due:"),timeBoxFrame) },
174{ "Duration: ", "Dauer: " },
175{ "Edit...", "Bearbeite..." },
176{ "Edit", "Bearbeite" },
177//{ "Edit Calendar Filters },
178{ "Edit Event...", "Bearbeite Ereignis..." },
179{ "Edit Event", "Bearbeite Ereignis" },
180//{ "Edit exceptions"), Ok|Cancel },
181{ "EditorBox:", "Editor Fenster:" },
182{ "Edit Recurrence Range", "Bearbeite Wiederholung" },
183//{ "&Edit..."),this,SLOT(popupEdit()))) },
184{ "Edit Todo...", "Berabeite Todo..." },
185{ "Edit To-Do", "Todo bearbeiten" },
186//{ "Email:" ) ) },
187{ "E&mail address:", "E&mail Adresse" },
188{ "(EmptyEmail)" , "(KeineEmail)" },
189{ "(EmptyName)", "(KeinName)" },
190//{ "Enable automatic saving of calendar") },
191//{ "Enable group scheduling") },
192//{ "Enable project view") },
193//{ "Enable Recurrence"), this ) },
194//{ "Enable scrollbars in month view cells") },
195//{ "Enable tooltips displaying summary of ev.") },
196//{ "End after"), rangeBox ) },
197//{ "End by:"), rangeBox ) },
198//{ "End Date")) },
199{ "End:", "Ende:" },
200//{ "End Time", "E)) },
201{ "English", "Englisch" },
202//{ "Enter filter name: },
203//{ "Error", "Fehler" },
204//{ "Error loading template file '%1'." },
205//{ "Event already exists in this calendar.") },
206{ "Event", "Ereignis" },
207{ "Event list", "Ereignis Liste" },
208//{ "Event list view uses full window") },
209//{ "Events and To-Dos that need a reply:") + "</h2>\n" },
210//{ "Events: ") + "</h2>\n" },
211//{ "Events have to be completely included"), topFrame) },
212//{ "Events"),incidenceGroup) },
213{ "Event Viewer:", "Ereignis Anzeige" },
214//{ "Event Viewer"),Ok|User1,Ok,false },
215//{ "Event will be sent to:")+"</h4>" },
216//{ "every"), this ) },
217{ "Exceptions...", "Ausnahmen..." },
218{ "Exceptions", "Ausnahmen" },
219{ "Exclude holidays", "Ohne Ferien" },
220{ "Exclude Saturdays", "Ohne Samstage" },
221//{ "Export to HTML with every save"),&(KOPrefs::instance()->mHtmlWithSave) },
222{ "Feb", "Feb" },
223{ "February", "Februar" },
224//{ "Filter disabled },
225//{ "Filter position: ") + QString::number ( mSelectionCombo->currentItem()+1 )) },
226//{ "Filter selected: },
227{ "&Find", "Finden" },
228{ "Fonts", "Zeichensätze" },
229//{ "Force take local entry always")) },
230//{ "Force take remote entry always")) },
231//{ "Form1" ) ) },
232//{ "Free Busy Object")) },
233{ "Free", "Frei" },
234{ "Friday", "Freitag" },
235{ "Fri", "Fr" },
236//{ "From: %1 To: %2 %3").arg(from).arg(to },
237//{ "From:"),rangeWidget)) },
238{ "Full &name:", "Vor- und &Nachname:" },
239//{ "Full path and file name required!"), topFrame) },
240{ "General", "Allgemein" },
241{ "German", "Deutsch" },
242{ "Gifts", "Geschenke" },
243//{ "Group Automation"),0 },
244//{ "Group Scheduling"),0 },
245{ "Help", "Hilfe" },
246{ "Hide Dates", "Daten ausblenden" },
247{ "Highlight color:" "Hervorhebungsfarbe" },
248{ "Holiday color:", "Ferien Farbe" },
249{ "hour(s)", "Stunde(n)" },
250//{ "iCalendar")) },
251//{ "If attendee is in addressbook")) },
252//{ "If organizer is in addressbook")) },
253//{ "If requested from an email in addressbook")) },
254//{ "If this counter-event is a good proposal for your event, press 'Accept'. All Attendees will then get the new version of this event },
255//{ "In %1 days: ").arg( i ) + "</font></em>"+day },
256//{ "Incomplete Todo:") + "</strong></big></big>\n" },
257{ "Information", "Information" },
258{ "Invalid search expression,\ncannot perform ", "Kann Suche nicht ausführen" },
259{ "Jan", "Jan" },
260{ "January", "Januar" },
261{ "JournalView:", "Journal Ansicht" },
262{ "Jul", "Jul" },
263{ "July", "Juli" },
264{ "Jump to date", "Springe zum Datum" },
265{ "June", "Juni" },
266{ "Jun", "Jun" },
267{ "Kids", "Kinder" },
268//{ "KMail", "KMail" },
269{ "KO/E Find ", "KO/E Suchen " },
270{ "KO/E Find: ", "KO/E Suchen: " },
271{ "KO/Pi is starting ... ", "KO/Pi startet ..." },
272{ "Language:(nyi)", "Sprache" },
273{ "Language:", "Sprache" },
274{ "Large", "Etwas mehr" },
275{ "List View:", "Listenansicht" },
276{ "Load/Save", "Laden/Speichern" },
277{ "Load Template", "Lade Vorlage" },
278{ "Locale", "Spracheinstellung" },
279{ "Local temp file:", "Lokales temp. Datei:" },
280//"Local temp file:\n "
281//"Local temp file:\n..."
282{ "Location: ", "Ort: " },
283{ "Location:", "Ort:" },
284{ "Mail client", "Mail Programm" },
285{ "Mail Client", "Mail Programm" },
286{ "March", "März" },
287{ "Mar", "Mär" },
288{ "May", "Mai" },
289{ "M. Bains line:", "M. Bains Linie:" },
290{ "Medium", "Medium" },
291{ "Method", "Methode" },
292{ "minute(s)", "Minute(n)" },
293{ "Monday", "Montag" },
294{ "Mon", "Mo" },
295{ "Monthly", "Monatlich" },
296{ "Month not long enough", "Monat ist nicht lang genug" },
297{ "month(s)", "Monat(e)" },
298{ "Month view:", "Monatsansicht" },
299{ "Month view uses category colors", "Monatsansicht benutzt die Kategorie Farben" },
300{ "Move &Down", "Nach unten verschieben" },
301{ "Move &Up", "Nach oben verschieben" },
302{ "Name:", "Name:" },
303{ "Name", "Name" },
304{ "\nAre you sure you want\nto delete this event?", "Sind Sie sicher, dass\n sie das Ereignis löschen möchten?" },
305{ "%n Days", "%n Tage" },
306{ "Never", "Nie" },
307{ "New event...", "Neues Ereignis..." },
308{ "New event", "Neues Ereignis" },
309{ "New Events/Todos should", "Meue Ereignisse/Todos sollten" },
310{ "&New", "&Neu" },
311{ "New", "Neu", },
312{ "New Sub-Todo...", "Neues Sub-Todo..." },
313{ "New Todo...", "Neues Todo..." },
314{ "New Todo", "Neues Todo" },
315{ "Next Alarm: ", "Nächster Alarm: ", },
316{ "&Next Day", "&Nächster Tag", },
317{ "Next days view uses full window", "Die Ansicht des nächsten Tages maximieren" },
318{ "Next month", "Nächster Monat" },
319{ "&Next Week", "&Nächste Woche" },
320{ "Next year", "Nächstes Jahr" },
321{ "Next Year", "Nächstes Jahr" },
322{ "%n h", "%n Std" },
323//"\n \nTry command on console to get more\ndetailed info about the reason.\n"
324//{ "nobody@nowhere", " },
325{ "No ending date", "Kein End-Datum", },
326{ "No event, nothing to do.", "Kein Ereignis, nichts zu tun.", },
327{ "No event selected.", "Kein Ereignis selektiert" },
328//{ "No event/todo were found matching\nyour search expression.\nUse the wildcard characters\n ' * ' and ' ? ' where needed."));"KO/E Find ")) },
329{ "No", "Nein" },
330{ "No program set", "Kein Programm ausgewählt", },
331{ "Normal", "Normal" },
332{ "[No selection]", "Keine Selektion", },
333{ "No sound set", "Kein Sound ausgewählt", },
334{ "no time ", "keine Zeit ", },
335{ "no time", "keine Zeit", },
336{ "No Time", "Keine Zeit" },
337{ "November", "November" },
338{ "Nov", "Nov", },
339{ "\nThis event recurs\nover multiple dates.\n", "\nDieses Ereignis wiederholt sich an mehreren Tagen.\n" },
340//{ "occurrence(s)"), rangeBox ) },
341{ "October", "Oktober" },
342{ "Oct", "Okt", },
343//{ "O-due!", " },
344//{ "Okay, another question:\n\nDo you really want\nto erase your complete disk?\nI hope, the decision is now\na little bit easier! },
345{ "&OK", "&OK" },
346{ "Ok+Show!", "Ok+Anzeigen" },
347{ "Organizer: %1","Organizer %1" },
348{ "Organizer","Organizer" },
349//{ "Overdue To-Do:") + "</h2>\n" },
350{ "Owner: ", "Besitzer: " },
351{ "Owner:", "Besitzer:" },
352{ "<p><b>Priority:</b> %2</p>", "<p><b>Priorität:</b> %2</p>" },
353//{ "Personal Travel", },
354//{ "<p><i>%1 % completed</i></p>" },
355{ "Pick a date to display", "Wähle einen Tag zum anzeigen aus" },
356//{ "Playing '%1'").arg(fileName) },
357//{ "Playing '%1'").arg(mAlarmSound) },
358//{ "Please specify a valid due date.")) },
359//{ "Please specify a valid end date, for example '%1'." },
360//{ "Please specify a valid start date.")) },
361//{ "Please specify a valid start date, for example '%1'." },
362//{ "Please specify a valid start time.")) },
363//{ "Please specify a valid start time, for example '%1'." },
364//{ "Preferences - some settings need a restart (nr)")) },
365{ "Preferences - some settings need a restart (nr)", "Einstellungen - teilweise Neustart erforderlich" },
366{ "&Previous Day", "Vorheriger Tag" },
367{ "Previous month", "Vorheriger Monat" },
368{ "Previous Month", "Vorheriger Monat" },
369{ "&Previous Week", "Vorherige Woche" },
370{ "Previous year", "Vorheriges Jahr" },
371{ "Previous Year", "Vorheriges Jahr" },
372{ "Printing", "Drucken" },
373//{ "Prio")) },
374//{ "Priority:"), h) },
375{ "Proceed", "Weiter" },
376//{ "Purge },
377//{ "read-only") + ")</em>") },
378{ "Recur every", "Wiederh. alle" },
379{ "Recur in the month of", "Wiederh. im Monat" },
380{ "Recur on the", "Wiederh. am" },
381{ "Recur on this day", "Wiederh. am diesen Tag" },
382{ "Recurrence Range...", "Wiederholungs Zeitraum..." },
383{ "Recurrence Range", "Wiederholungs Zeitraum" },
384{ "Recurrence Rule", "Wiederholungs Regel" },
385{ "Recurrence", "Wiederholung" },
386{ "Recurs", "Wiederhole" },
387"&Reject", "Abweisen",
388{ "Reminder:", "Erinnerung:" },
389//"Remote file:\n "
390//"Remote file:\n..."
391//{ "Remote file:"), topFrame) },
392//{ "Remote IP:"), topFrame) },
393//{ "Remote passwd:"), topFrame) },
394//{ "Remote syncing (via ssh/scp) network settings "), topFrame) },
395//{ "Remote user:"), topFrame) },
396{ "&Remove", "Entfe&rnen" },
397{ "Remove", "Entfernen" },
398{ "Request response", "Bemerkung anfordern" },
399//{ "Retrieve &Messages" ) ) },
400{ "Role:", "Rolle:" },
401{ "Role", "Rolle" },
402//{ "RSVP"),35) },
403//{ "Running '%1'").arg(fileName) },
404//{ "Running '%1'").arg(mAlarmProgram) },
405{ "Sat", "Sa" },
406{ "Saturday", "Samstag" },
407//{ "Save Template"), Ok | Cancel, Ok, parent, 0 },
408//{ "Scheduler - Incoming Messages" ) ) },
409//{ "Scheduler Mail Client"),&(KOPrefs::instance()->mIMIPScheduler) },
410//{ "Scheduler Mails Should Be"),&(KOPrefs::instance()->mIMIPSend) },
411//{ "Scheduler - Outgoing Messages" ) ) },
412{ "Search for:", "Suche nach:" },
413{ "Search In", "Suche in" },
414{ "Search", "Suche" },
415{ "Select Addresses", "Wähle Adressen" },
416{ "Select all", "Wähle alles" },
417{ "Select a month", "Wähle Monat" },
418//{ "Select a template to load:"), templates, 0, &ok ) },
419{ "Select a week", "Wähle Woche" },
420{ "Select a year", "Wähle Jahr" },
421//{ "selected emails")) },
422//{ "Select Template Name"), topFrame },
423//{ "Select the current day")) },
424//{ "Send copy to owner when mailing events") },
425{ "Send directly", "Sende direkt" },
426//{ "Sendmail")) },
427{ "&Send Messages", "&Sende Nachrichten", },
428//{ "Send to outbox")) },
429{ "Sep", "Sep" },
430{ "September", "September" },
431//{ "Set your status },
432//{ "Set Your Status")) },
433{ "Shopping", "Einkaufen" },
434{ "Short date in (WN/E) view", "Kurzdatum in (WN/E) Anzeige" },
435{ "Show Dates", "Zeige Daten" },
436//{ "Show events that recur daily in date nav.") },
437{ "Show Event...", "Zeige Ereignis..." },
438//{ "Show ev. that recur weekly in date nav.") },
439//{ "Show Marcus Bains line") },
440//{ "Show seconds on Marcus Bains line") },
441//{ "Show summary after syncing") },
442{ "Show time as:", "Zeige Zeit als" },
443{ "Show Todo...", "Zeige To-Do" },
444//{ "Show topmost todo prios in What's N.:") },
445//{ "Show topmost todo prios in What's Next:") },
446//{ "Show vertical screen (Needs restart)") },
447{ "&Show", "Zeige" },
448{ "Show...", "Zeige..." },
449{ "Show", "Zeige" },
450{ "Small", "Klein" },
451{ "Sorry", "Entschuldigung" },
452//"Sorry, the copy command failed!\nCommand was:\n"
453//{ "Sort Id")) },
454{ "Start:", "Anfang:" },
455{ "Start Date", "Start Datum" },
456{ "Start Time", "Start Zeit" },
457{ "Status:", "Status:" },
458{ "Status","Status:" },
459//{ "Stretched TB", "
460{ "Summaries","Zusammenfassungen" },
461{ "Summary:","Zusammenfassung:" },
462{ "Summary","Zusammenfassung" },
463{ "Sunday", "Sonntag" },
464{ "Sun", "So" },
465//{ "Sync Network"),0,0) },
466{ "Sync preferences:", "Sync Einstellungen" },
467{ "Sync Prefs", "Sync Einstellungen" },
468{ "Syncronize", "Daten abgleich" },
469//{ "Take local entry on conflict")) },
470//{ "Take newest entry on conflict")) },
471//{ "Take remote entry on conflict")) },
472//{ "Template '%1' does not contain a valid Todo." },
473//{ "Template does not contain a valid Event." },
474{ "Template...", "Vorlage..." },
475//{ "The event ends before it starts.\n },
476//{ "The event has no attendees.")) },
477//{ "The journal entries can not be\nexported to a vCalendar file.") },
478//{ "The organizer %1", " },
479//{ "The start date cannot be after the due date.")) },
480//{ " - they have the same unique ID "), topFrame) },
481{ "This day", "Dieser Tag" },
482{ "This is an experimental feature. ", "Dieses Feature ist experimentel" },
483//{ "This is a recurring event.") + "</em>") },
484{ "This item will be\npermanently deleted.", "Dieser Eintrag wird\nkomplett gelöscht." },
485{ "This item will be permanently deleted.", "Dieser Eintrag wird komplett gelöscht." },
486{ "Thu", "Do" },
487{ "Thursday", "Donnerstag" },
488{ "Time associated", "Dazugehörige Zeit" },
489{ "Time bar:", "Zeit Intervall" },
490{ "Time && Date", "Zeit und Datum" },
491{ "Time Format", "Zeit Format" },
492{ "Time Labels:", "Zeit Markierungen:" },
493{ "Time: ", "Zeit: " },
494{ "Timezone:", "Zeitzone:" },
495{ "Tiny", "Sehr klein" },
496{ "To: ", "An: " },
497{ "To:", "An:" },
498{ "Today: ", "Heute: " },
499//{ "To-Do: %1 },
500//{ "Todo due today color:") },
501//{ "To-do items:"),this) },
502//{ "Todo overdue color:") },
503//{ "Todos"),incidenceGroup) },
504{ "Todo", "Todo" },
505{ "To-do view shows completed Todos", "To-do Anzeige zeigt erledigte To-dos" },
506{ "ToDoView:", "Todo Anzeige:" },
507{ "Toggle Alarm", "Wechsle Alarm" },
508{ "Toggle Allday", "Umschalten Ganztag" },
509//{ "toggle completed To-Dos","Hide/Show Completed") },
510//{ "toggle completed To-Dos","Hide/Show Completed") },
511{ "Tomorrow: ", "Morgen: " },
512// { "Toolbar", "Zugriffsleiste" },
513{ "Tue", "Di" },
514{ "Tuesday", "Dienstag" },
515{ "Two entries are in conflict, if: ", "Zwei Einträge haben einen Konflikt, wenn:" },
516{ "Unable to find template '%1'.", "Kann Vorlage '%1' nicht finden." },
517{ "University", "Universität" },
518{ "Unknown", "Unbekannt" },
519{ "Up", "Hinauf" },
520//{ "&Use email settings from Control Center", " },
521{ "Use password (if not, ask when syncing)", "Passwort: (sonst jedesmal anfragen)" },
522{ "User defined (next page)", "Benutzer definiert (Nächste Seite)" },
523{ "User long date", "Benutz. lang. Datum" },
524{ "User short date", "Benutz. kurz. Datum" },
525//{ "vCalendar")) },
526{ "View", "Ansicht" },
527{ "View", "Anzeige" },
528{ "View Fonts", "Zeige Schriften" },
529{ "Views", "Ansichten" },
530//{ "VIP") },
531{ "Wed", "Mi" },
532{ "Wednesday", "Mittwoch" },
533{ "Week %1", "Woche %1" },
534{ "Weekly", "Wöchentlich" },
535//{ "week(s) on:"), this ) },
536{ "Week starts on Sunday", "Wochenanfang Sonntags" },
537{ "What's Next View:", "What's Next Anzeige" },
538{ "What's next ?", "Was kommt als nächstes?" },
539{ "Working Hours", "Arbeitsstunden" },
540{ "Working hours color:", "Farbe der Arbeitsstunden" },
541{ "Write back existing entries only", "Nur exisitierende Einträge zurückschreiben" },
542{ "Write back synced file", "Syncronisierte Datei zurückschreiben" },
543{ "Yearly", "Jährlich" },
544{ "year(s)", "Jahr(e)" },
545{ "Yes", "Ja" },
546{ "You have %d item(s) selected.\n", "Sie haben %d Einträge ausgewählt.\n" },
547{ "You have to restart KOrganizer for this setting to take effect.","Sie müssem Korganizer neu starten, damit diese Einstellung aktiviert wird." },
548//{ "Zoom In", "Hineinzoomen" },
549//{ "Zoom Out", "Herauszoomen" },