summaryrefslogtreecommitdiffstats
path: root/lib/kotext/KoTextObject.h
blob: a463d0fcc9539ece80de8e12f1503875f712d9e0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
/* This file is part of the KDE project
   Copyright (C) 2001-2006 David Faure <faure@kde.org>

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public
   License as published by the Free Software Foundation; either
   version 2 of the License, or (at your option) any later version.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public License
   along with this library; see the file COPYING.LIB.  If not, write to
   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
*/

#ifndef kotextobject_h
#define kotextobject_h

#include <KoRichText.h>
#include "KoChangeCaseDia.h"
#include "KoStyleCollection.h"
#include "KoTextDocument.h"
#include <koffice_export.h>

class KoSavingContext;
class KCommand;
class KoTextFormat;
class TQProgressDialog;
class KoLinkVariable;
class KoVariable;

//#define TIMING_FORMAT
//#include <tqdatetime.h>

/**
 * The KoTextFormatInterface is a pure interface that allows access to the
 * "current text format". This is implemented by both KoTextObject and KoTextView.
 * For KoTextView, it's the format under the cursor.
 * For KoTextObject, it's the global format.
 * By changing this format and calling setFormat (with the appropriate flags),
 * it's possible to implement "setBold", "setItalic" etc. only once, whether it applies
 * to a text selection or to complete text objects.
 */
class KOTEXT_EXPORT KoTextFormatInterface
{
public:
    KoTextFormatInterface() {}
    virtual ~KoTextFormatInterface() {}

    /** Interface for accessing the current format */
    virtual KoTextFormat * currentFormat() const = 0;

    virtual bool rtl() const = 0;

    /**
     * Interface for setting the modified format
     * @param format can be a temporary format
     * @param zoomFont set to true if the font size was used-specified (e.g. in KoFontDia)
     * @param flags see enum KoTextFormat::Flags
     */
    virtual KCommand *setFormatCommand( const KoTextFormat *format, int flags, bool zoomFont = false ) = 0;

    /** Interface for accessing the current parag tqlayout */
    virtual const KoParagLayout * currentParagLayoutFormat() const = 0;

    /** Interface for changing the paragraph tqlayout.
     * @param newLayout pointer to the new tqlayout to apply
     * @param flags one of the KoParagLayout flags
     * @param marginIndex type of margin. Only used if flags==KoParagLayout::Margins
     */
    virtual KCommand *setParagLayoutFormatCommand( KoParagLayout *newLayout, int flags, int marginIndex=-1) = 0;

    virtual KCommand *setChangeCaseOfTextCommand(KoChangeCaseDia::TypeOfCase _type)=0;

    KoTextDocCommand *deleteTextCommand( KoTextDocument *textdoc, int id, int index, const TQMemArray<KoTextStringChar> & str, const CustomItemsMap & customItemsMap, const TQValueList<KoParagLayout> & oldParagLayouts );

    void setParagLayoutFormat( KoParagLayout *newLayout,int flags, int marginIndex=-1);
    void setFormat( KoTextFormat * newFormat, int flags, bool zoomFont = false );

    // Warning: use the methods that return a command! The others just leak the commands away
    //void setBold(bool on);
    KCommand *setBoldCommand(bool on);
    //void setItalic(bool on);
    KCommand *setItalicCommand(bool on);
    //void setUnderline(bool on);
    KCommand *setUnderlineCommand(bool on);
    //void setStrikeOut(bool on);
    KCommand *setDoubleUnderlineCommand( bool on );
    KCommand *setUnderlineColorCommand( const TQColor &color );
    KCommand *setStrikeOutCommand(bool on);
    //void setTextColor(const TQColor &color);
    KCommand *setTextColorCommand(const TQColor &color);
    //void setPointSize( int s );
    KCommand *setPointSizeCommand( int s );
    //void setFamily(const TQString &font);
    KCommand *setFamilyCommand(const TQString &font);
    //void setTextSubScript(bool on);
    KCommand *setTextSubScriptCommand(bool on);
    //void setTextSuperScript(bool on);
    KCommand *setTextSuperScriptCommand(bool on);

    //void setDefaultFormat();
    KCommand *setDefaultFormatCommand();

    //void setTextBackgroundColor(const TQColor &);
    KCommand *setTextBackgroundColorCommand(const TQColor &);

    //void setAlign(int align);
    KCommand *setAlignCommand(int align);

    //void setMargin(TQStyleSheetItem::Margin m, double margin);
    KCommand *setMarginCommand(TQStyleSheetItem::Margin m, double margin);

    //void setTabList(const KoTabulatorList & tabList );
    KCommand *setTabListCommand(const KoTabulatorList & tabList );

    //void setBackgroundColor(const TQColor & color );
    KCommand *setBackgroundColorCommand(const TQColor & color );

    //void setCounter(const KoParagCounter & counter );
    KCommand *setCounterCommand(const KoParagCounter & counter );

    KCommand *setLanguageCommand(const TQString &);

    KCommand *setShadowTextCommand( double shadowDistanceX, double shadowDistanceY, const TQColor& shadowColor );

    KCommand *setHyphenationCommand( bool _b );


    KCommand *setFontAttributeCommand( KoTextFormat::AttributeStyle _att);

    KCommand *setRelativeTextSizeCommand( double _size );

    KCommand *setOffsetFromBaseLineCommand( int _offset );

    KCommand *setWordByWordCommand( bool _b );


    TQColor textColor() const;
    TQFont textFont() const;
    TQString textFontFamily()const;
    TQString language() const;
    TQColor textBackgroundColor()const;
    TQColor textUnderlineColor()const;

    KoTextFormat::UnderlineType underlineType()const;
    KoTextFormat::StrikeOutType strikeOutType()const;
    KoTextFormat::UnderlineStyle underlineStyle()const;
    KoTextFormat::StrikeOutStyle strikeOutStyle()const;



    bool textUnderline()const;
    bool textDoubleUnderline()const;

    bool textBold()const;
    bool textStrikeOut()const;
    bool textItalic() const;
    bool textSubScript() const;
    bool textSuperScript() const;
    double shadowDistanceX() const;
    double shadowDistanceY() const;
    TQColor shadowColor() const;
    KoTextFormat::AttributeStyle fontAttribute() const;
    double relativeTextSize() const;
    int offsetFromBaseLine()const;
    bool wordByWord()const;
    bool hyphenation()const;
};

/**
 * The KoTextObject is the high-level object that contains a KoTextDocument
 * (the list of paragraphs), and takes care of the operations on it (particularly
 * the undo/redo commands).
 * Editing the text isn't done by KoTextObject but by KoTextView (document/view design).
 */
class KOTEXT_EXPORT KoTextObject : public TQObject, public KoTextFormatInterface
{
    Q_OBJECT
  TQ_OBJECT
public:
    /** Constructor.
     * This constructor creates the contained KoTextDocument automatically.
     *
     * @param zh the zoom handler (to be passed to the KoTextDocument ctor)
     * @param defaultFont the font to use by default (see KoTextFormatCollection)
     * @param defaultLanguage the language to use by default (see KoTextFormatCollection)
     * @param defaultHyphenation the default setting for hyphenation (see KoTextFormatCollection)
     * @param defaultStyle the style to use by default (initial pararaph, and when deleting a used style)
     * @param tabStopWidth the global value for the tabstop width
     * @param tqparent tqparent widget for this object
     * @param name name for this object
     *
     */
    KoTextObject( KoTextZoomHandler *zh, const TQFont& defaultFont, const TQString &defaultLanguage,
                  bool defaultHyphenation, KoParagStyle* defaultStyle, int tabStopWidth = -1,
                  TQObject* tqparent = 0, const char *name = 0 );

    /** Alternative constructor.
     * This constructor allows to use a derived class from KoTextDocument.
     *
     * @param textdoc the text document to use in this text object. Ownership is transferred
     * to the text object.
     * @param defaultStyle the style to use by default (initial pararaph, and when deleting a used style)
     * @param tqparent tqparent widget for this object
     * @param name name for this object
     */
    KoTextObject( KoTextDocument *textdoc, KoParagStyle* defaultStyle,
                  TQObject* tqparent = 0, const char *name = 0 );

    virtual ~KoTextObject();


    static const char * acceptSelectionMimeType();
    /// Check if the mimesource @p mime provides one of the OASIS mimetypes,
    /// and if so, return it. Otherwise return an empty string.
    static TQCString providesOasis( TQMimeSource* mime );

    void setNeedSpellCheck(bool b);
    bool needSpellCheck() const { return m_needsSpellCheck;}
    void setProtectContent(bool b) { m_protectContent = b; }
    bool protectContent() const{ return m_protectContent;}
    /**
     * Return the text document contained in this KoTextObject
     */
    KoTextDocument *textDocument() const { return textdoc; }

    void setAvailableHeight( int avail ) { m_availableHeight = avail; }
    int availableHeight() const;

    void undo();
    void redo();
    /** Terminate our current undo/redo info, to start with a new one */
    void clearUndoRedoInfo();

    /** return true if some text is selected */
    bool hasSelection() const { return textdoc->hasSelection( KoTextDocument::Standard, true ); }
    /** returns the selected text [without formatting] if hasSelection() */
    TQString selectedText( KoTextDocument::SelectionId selectionId = KoTextDocument::Standard ) const {
        return textdoc->selectedText( selectionId );
    }
    /** returns true if the given selection has any custom item in it */
    bool selectionHasCustomItems( KoTextDocument::SelectionId selectionId = KoTextDocument::Standard ) const;

    enum InsertFlag {
        DefaultInsertFlags = 0,
        CheckNewLine = 1, /// < if true, the text to be inserted is checked for '\\n' (as a paragraph delimiter)
        OverwriteMode = 2,
        DoNotRemoveSelected = 4, ///< whether to remove selected text before
        DoNotRepaint = 8         ///< usually we tqrepaint in insert(), this allows to turn it off
    };

    /**
     * The main "insert" method, including undo/redo creation/update.
     *
     * @param cursor the insertion point
     * @param currentFormat the current textformat, to apply to the inserted text
     * @param text the text to be inserted
     * @param insertFlags flags, see InsertFlag
     * @param commandName the name to give the undo/redo command if we haven't created it already
     * @param customItemsMap the map of custom items to include in the new text
     * @param selectionId which selection to use (See KoTextDocument::SelectionId)
     */
    void insert( KoTextCursor * cursor, KoTextFormat * currentFormat, const TQString &text,
                 const TQString & commandName,
                 KoTextDocument::SelectionId selectionId = KoTextDocument::Standard,
                 int insertFlags = DefaultInsertFlags, // KDE4: TODO use TQFlags
                 CustomItemsMap customItemsMap = CustomItemsMap() );

    /**
     * Remove the text currently selected, including undo/redo creation/update.
     * @param cursor the caret position
     * @param selectionId which selection to remove (usually Standard)
     * @param cmdName the name to give the undo/redo command, if we haven't created it already
     * @param createUndoRedo create an undo history entry for this removal
     */
    void removeSelectedText( KoTextCursor * cursor, KoTextDocument::SelectionId selectionId = KoTextDocument::Standard,
                             const TQString & cmdName = TQString(), bool createUndoRedo=true  );

    KCommand * replaceSelectionCommand( KoTextCursor * cursor, const TQString & replacement,
                                        const TQString & cmdName,
                                        KoTextDocument::SelectionId selectionId = KoTextDocument::Standard,
                                        int insertFlags = DefaultInsertFlags, // KDE4: TODO use TQFlags
                                        CustomItemsMap customItemsMap = CustomItemsMap() );
    KCommand * removeSelectedTextCommand( KoTextCursor * cursor, KoTextDocument::SelectionId selectionId, bool tqrepaint = true );
    KCommand* insertParagraphCommand( KoTextCursor * cursor );

    /**
     * Paste plain text at the given @p cursor
     * @param cursor location to paste text
     * @param text the text to paste
     * @param currentFormat format to apply to the pasted text
     * @param removeSelected @c true when pasting with the keyboard, but @c false when dropping text.
     *
     * @todo Can currentFormat be NULL?
     * @todo Besides saying when removeSelected is @c true, perhaps explain
     *       what it does (presumably, removes the selection and replaces it
     *       with the pasted text).
     */
    void pasteText( KoTextCursor * cursor, const TQString & text, KoTextFormat * currentFormat,
                    bool removeSelected );
    void selectAll( bool select );

    /** Highlighting support (for search/replace, spellchecking etc.).
     * Don't forget to ensure the paragraph is visible.
     */
    void highlightPortion( KoTextParag * parag, int index, int length, bool tqrepaint );
    void removeHighlight( bool tqrepaint );

    /** Implementation of setFormatCommand from KoTextFormatInterface - apply change to the whole document */
    KCommand *setFormatCommand( const KoTextFormat *format, int flags, bool zoomFont = false );

    /** Set format changes on selection or current cursor.
        Returns a command if the format was applied to a selection */
    KCommand *setFormatCommand( KoTextCursor * cursor, KoTextFormat ** currentFormat, const KoTextFormat *format, int flags, bool zoomFont = false, KoTextDocument::SelectionId selectionId = KoTextDocument::Standard );

    enum KeyboardAction { // keep in sync with TQTextEdit
	ActionBackspace,
	ActionDelete,
	ActionReturn,
	ActionKill
    };
    /** Executes keyboard action @p action. This is normally called by
     * a key event handler. */
    void doKeyboardAction( KoTextCursor * cursor, KoTextFormat * & currentFormat, KeyboardAction action );

    // -- Paragraph settings --
    KCommand * setCounterCommand( KoTextCursor * cursor, const KoParagCounter & counter, KoTextDocument::SelectionId selectionId = KoTextDocument::Standard );
    KCommand * setAlignCommand( KoTextCursor * cursor, int align , KoTextDocument::SelectionId selectionId = KoTextDocument::Standard);
    KCommand * setLineSpacingCommand( KoTextCursor * cursor, double spacing, KoParagLayout::SpacingType _type,KoTextDocument::SelectionId selectionId = KoTextDocument::Standard );
    KCommand * setBordersCommand( KoTextCursor * cursor, const KoBorder& leftBorder, const KoBorder& rightBorder, const KoBorder& topBorder, const KoBorder& bottomBorder, KoTextDocument::SelectionId selectionId = KoTextDocument::Standard );
    KCommand * setJoinBordersCommand( KoTextCursor * cursor, bool join, KoTextDocument::SelectionId selectionId = KoTextDocument::Standard );
    KCommand * setMarginCommand( KoTextCursor * cursor, TQStyleSheetItem::Margin m, double margin, KoTextDocument::SelectionId selectionId = KoTextDocument::Standard);
    KCommand* setTabListCommand( KoTextCursor * cursor,const KoTabulatorList & tabList , KoTextDocument::SelectionId selectionId = KoTextDocument::Standard );
    KCommand* setBackgroundColorCommand( KoTextCursor * cursor,const TQColor & color , KoTextDocument::SelectionId selectionId = KoTextDocument::Standard );

    KCommand * setParagDirectionCommand( KoTextCursor * cursor, TQChar::Direction d, KoTextDocument::SelectionId selectionId = KoTextDocument::Standard );

    /**
     * Apply a KoParagStyle to a selection.
     * @param cursor the current cursor; used if there is no selection. Can be 0L if there is one.
     * @param style the KoParagStyle to apply
     * @param selectionId the id of the selection, usually Standard or Temp
     * @param paragLayoutFlags which settings from the paragraph tqlayout to apply
     * @param formatFlags which settings from the text format to apply
     * @param createUndoRedo if true, an undo/redo command will be created and emitted
     * @param interactive if true, the text will be reformatted/repainted to show the new style
     */
    void applyStyle( KoTextCursor * cursor, const KoParagStyle * style,
                     KoTextDocument::SelectionId selectionId = KoTextDocument::Standard,
                     int paragLayoutFlags = KoParagLayout::All, int formatFlags = KoTextFormat::Format,
                     bool createUndoRedo = true, bool interactive = true );

    /**
     * Helper for applyStyle. Can also be called directly, so that the command isn't emitted,
     * e.g. to put it into a macro-command.
     * @return the command for 'apply style', or 0L if createUndoRedo is false.
     */
    KCommand* applyStyleCommand( KoTextCursor * cursor, const KoParagStyle * style,
                     KoTextDocument::SelectionId selectionId = KoTextDocument::Standard,
                     int paragLayoutFlags = KoParagLayout::All, int formatFlags = KoTextFormat::Format,
                     bool createUndoRedo = true, bool interactive = true );


    /** Update the paragraph that use the given style, after this style was changed.
     *  The flags tell which changes should be applied.
     *  @param changed map of styles that have changed
     */
    void applyStyleChange( KoStyleChangeDefMap changed );
    /** Set format changes on selection or current cursor.
        Creates a command if the format was applied to a selection */
    void setFormat( KoTextCursor * cursor, KoTextFormat ** currentFormat, KoTextFormat *format, int flags, bool zoomFont = false );


    /**
     * Support for treating the whole textobject as a single object
     * Use this format for displaying the properties (font/color/...) of the object.
     * Interface for accessing the current format
     */
    virtual KoTextFormat * currentFormat() const;

    /**
     * Use this format for displaying the properties (Align/counter/...) of the object
     */
    virtual const KoParagLayout * currentParagLayoutFormat() const;

    virtual bool rtl() const;

    /**
     * Support for changing the format in the whole textobject
     */
    virtual KCommand *setParagLayoutFormatCommand( KoParagLayout *newLayout, int flags, int marginIndex=-1);

    // common for setParagLayoutFormatCommand above and KoTextView::setParagLayoutFormatCommand
    KCommand *setParagLayoutCommand( KoTextCursor * cursor, const KoParagLayout& paragLayout,
                                     KoTextDocument::SelectionId selectionId, int paragLayoutFlags,
                                     int marginIndex, bool createUndoRedo );
    /**
     * Support for changing the format in the whole textobject
     */
    virtual void setFormat( KoTextFormat * newFormat, int flags, bool zoomFont = false );

    /** Return the user-visible font size for this format (i.e. LU to pt conversion) */
    int docFontSize( KoTextFormat * format ) const;
    /** Return the font size in LU, for this user-visible font size in pt */
    int zoomedFontSize( int docFontSize ) const;

    /** Set the bottom of the view - in LU */
    void setViewArea( TQWidget* w, int maxY );
    /** Make sure that @p parag is formatted */
    void ensureFormatted( KoTextParag * parag, bool emitAfterFormatting = true );
    void setLastFormattedParag( KoTextParag *parag );

    static TQChar customItemChar() { return TQChar( s_customItemChar ); }

    // TQt should really have support for public signals
    void emitHideCursor() { emit hideCursor(); }
    void emitShowCursor() { emit showCursor(); }
    void emitEnsureCursorVisible() { emit ensureCursorVisible(); }
    void emitUpdateUI( bool updateFormat, bool force = false ) { emit updateUI( updateFormat, force ); }

    void typingStarted();
    void typingDone();

    /**
     * Abort the current formatMore() loop, or prevent the next one from starting.
     * Use with care. This is e.g. for KWFootNoteVariable, so that it can do
     * a frame tqlayout before formatting the main text again.
     * It is important to make sure that formatMore will be called again ;)
     */
    void abortFormatting();

    void selectionChangedNotify( bool enableActions = true );

    void emitNewCommand(KCommand *cmd);

    virtual KCommand *setChangeCaseOfTextCommand(KoChangeCaseDia::TypeOfCase _type);

    KCommand *changeCaseOfText(KoTextCursor *cursor, KoChangeCaseDia::TypeOfCase _type);
    TQString textChangedCase(const TQString& _text, KoChangeCaseDia::TypeOfCase _type);
    KCommand *changeCaseOfTextParag(int cursorPosStart, int cursorPosEnd,KoChangeCaseDia::TypeOfCase _type,KoTextCursor *cursor, KoTextParag *parag);

    void loadOasisContent( const TQDomElement &bodyElem, KoOasisContext& context, KoStyleCollection * styleColl );
    void saveOasisContent( KoXmlWriter& writer, KoSavingContext& context ) const;

    // Similar to KoTextDocument::loadOasisText but there's no newline inserted before the first paragraph
    // or after the last one - so it's possible to paste just a few chars.
    // It also handles m_lastFormatted
    KoTextCursor pasteOasisText( const TQDomElement &bodyElem, KoOasisContext& context,
                                 KoTextCursor& cursor, KoStyleCollection * styleColl );

#ifndef NDEBUG
    void printRTDebug(int);
#endif

    bool statistics( TQProgressDialog *progress, ulong & charsWithSpace, ulong & charsWithoutSpace, ulong & words, ulong & sentences, ulong & syllables, ulong & lines, bool selected );
    int numberOfparagraphLineSelected( KoTextParag *parag);

    /**
     * Return the variable at the given point (in document coordinates), if any
     */
    KoVariable* variableAtPoint( const TQPoint& iPoint ) const;

    /**
     * Return the variable at the given position, if any.
     * Passing KoTextView's m_cursor here is usually wrong, index must come from the variablePosition
     * value returned by KoTextCursor::place().
     */
    KoVariable* variableAtPosition( KoTextParag* parag, int index ) const;

    enum ParagModifyType { AddChar = 0, RemoveChar = 1, ChangeFormat = 2 };

signals:
    /** Emitted by availableHeight() when the available height hasn't been
     * calculated yet or is invalid. Connect to a slot that calls setAvailableHeight() */
    void availableHeightNeeded();

    /** Emitted by formatMore() after formatting a bunch of paragraphs.
     * KWord uses this signal to check for things like 'I need to create a new page'
     */
    void afterFormatting( int bottom, KoTextParag* m_lastFormatted, bool* abort );

    /**
     * Emitted by formatMore() when formatting a "Head 1" paragraph.
     * Used for the Section variable
     */
    void chapterParagraphFormatted( KoTextParag* parag );

    /** Emitted by formatMore() when formatting the first paragraph.
     */
    void formattingFirstParag();

    /** Emitted when a new command has been created and should be added to
     * the main list of commands (usually in the KoDocument).
     * Make sure to connect to that one, otherwise the commands will just leak away...
     */
    void newCommand( KCommand *cmd );

    /** Tell the world that we'd like some repainting to happen */
    void repaintChanged( KoTextObject * );

    void hideCursor();
    void showCursor();
    /** Special hack for undo/redo - used by KoTextView */
    void setCursor( KoTextCursor * cursor );
    /** Emitted when the formatting under the cursor may have changed.
     * The Edit object should re-read settings and update the UI. */
    void updateUI( bool updateFormat, bool force = false );
    /** Same thing, when the current format (of the edit object) was changed */
    void showCurrentFormat();
    /** The views should make sure the cursor is visible */
    void ensureCursorVisible();
    /** Tell the views that the selection changed (for cut/copy...) */
    void selectionChanged( bool hasSelection );

    void showFormatObject(const KoTextFormat &);

    // Keeping track of text modifications - not emitted during loading/closing.
    void paragraphCreated( KoTextParag* parag );
    void paragraphModified( KoTextParag* parag, int /*ParagModifyType*/, int pos, int length );
    void paragraphDeleted( KoTextParag* parag );

public slots:
    // The default arguments are those used by the formatTimer.
    // The return value is used by ensureFormatted
    bool formatMore( int count = 10, bool emitAfterFormatting = true );

    void emitRepaintChanged() { emit repaintChanged( this ); }

public: // made public for KWTextFrameSet...

    /** This prepares undoRedoInfo for a paragraph formatting change
     * If this does too much, we could pass an enum flag to it.
     * But the main point is to avoid too much duplicated code */
    void storeParagUndoRedoInfo( KoTextCursor * cursor, KoTextDocument::SelectionId selectionId = KoTextDocument::Standard );
    /** Copies a formatted char, <parag, position>, into undoRedoInfo.text, at position @p index. */
    void copyCharFormatting( KoTextParag *parag, int position, int index /*in text*/, bool moveCustomItems );
    void readFormats( KoTextCursor &c1, KoTextCursor &c2, bool copyParagLayouts = false, bool moveCustomItems = false );

    /**
     * The undo-redo structure holds the _temporary_ information for the current
     * undo/redo command. For instance, when typing "a" and then "b", we don't
     * want a command for each letter. So we keep adding info to this structure,
     * and when the user does something else and we call clear(), it's at that
     * point that the command is created.
     * See also the place-holder command (in fact an empty macro-command is created
     * right at the beginning, so that it's possible to undo at any time).
     */
    struct KOTEXT_EXPORT UndoRedoInfo { // borrowed from TQTextEdit
        enum Type { Invalid, Insert, Delete, Return, RemoveSelected };
        UndoRedoInfo( KoTextObject* textobj );
        ~UndoRedoInfo() {}
        void clear();
        bool valid() const;

        KoTextString text; // storage for formatted text
        int id; // id of first parag
        int eid; // id of last parag
        int index; // index (for insertion/deletion)
        Type type; // type of command
        KoTextObject* textobj; // tqparent
        CustomItemsMap customItemsMap; // character position -> qtextcustomitem
        TQValueList<KoParagLayout> oldParagLayouts;
        KoParagLayout newParagLayout;
        KoTextCursor *cursor; // basically a "mark" of the view that started this undo/redo info
        // If the view changes, the next call to checkUndoRedoInfo will terminate the previous view's edition
        KMacroCommand *placeHolderCmd;
    };
    /**
     * Creates a place holder for a command that will be completed later on.
     * This is used for the insert and delete text commands, which are
     * build delayed (see the UndoRedoInfo structure), in order to
     * have an entry in the undo/redo history asap.
     */
    void newPlaceHolderCommand( const TQString & name );
    void checkUndoRedoInfo( KoTextCursor * cursor, UndoRedoInfo::Type t );

    /** for KWTextFrameSet */
    UndoRedoInfo & undoRedoInfoStruct() { return undoRedoInfo; }

    void setVisible(bool vis) { m_visible=vis; }
    bool isVisible() const { return m_visible; }

private slots:
    void doChangeInterval();
    /** This is done in a singleShot timer because of macro-commands.
     * We need to do this _after_ terminating the macro command (for instance
     * in the case of undoing a floating-frame insertion, we need to delete
     * the frame first) */
    void slotAfterUndoRedo();
    void slotParagraphModified(KoTextParag *, int, int , int);
    void slotParagraphCreated(KoTextParag *);
    void slotParagraphDeleted(KoTextParag *);
private:
    void init();

private:
    class KoTextObjectPrivate;
    KoTextObjectPrivate* d;
    /** The text document, containing the paragraphs */
    KoTextDocument *textdoc;

    /** The style to use by default (initial pararaph, and when deleting a used style)
        TODO: check that we support 0 */
    KoParagStyle* m_defaultStyle;

    bool m_visible;

    /** Currently built undo/redo info */
    UndoRedoInfo undoRedoInfo;

    /** All paragraphs up to this one are guaranteed to be formatted.
        The idle-time formatting (formatMore()) pushes this forward.
        Any operation on a paragraph pushes this backward. */
    KoTextParag *m_lastFormatted;
    /** Idle-time formatting */
    TQTimer *formatTimer, *changeIntervalTimer;
    int interval;

    /** The total height available for our text object at the moment */
    int m_availableHeight;
    /** Store the "needs" of each view */
    TQMap<TQWidget *, int> m_mapViewAreas;

    //TQPtrDict<int> m_origFontSizes; // Format -> doc font size.

    bool m_highlightSelectionAdded;

#ifdef TIMING_FORMAT
    TQTime m_time;
#endif

    static const char s_customItemChar;
    bool m_needsSpellCheck;
    bool m_protectContent;
};

#endif