File indexing completed on 2024-05-12 04:21:29

0001 
0002 /*
0003    Copyright (c) 2003-2007 Clarence Dang <dang@kde.org>
0004    All rights reserved.
0005 
0006    Redistribution and use in source and binary forms, with or without
0007    modification, are permitted provided that the following conditions
0008    are met:
0009 
0010    1. Redistributions of source code must retain the above copyright
0011       notice, this list of conditions and the following disclaimer.
0012    2. Redistributions in binary form must reproduce the above copyright
0013       notice, this list of conditions and the following disclaimer in the
0014       documentation and/or other materials provided with the distribution.
0015 
0016    THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
0017    IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
0018    OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
0019    IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
0020    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
0021    NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0022    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
0023    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0024    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
0025    THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0026 */
0027 
0028 
0029 #ifndef KP_VIEW_MANAGER_H
0030 #define KP_VIEW_MANAGER_H
0031 
0032 
0033 #include <QObject>
0034 
0035 
0036 class QCursor;
0037 class QRegion;
0038 class QRect;
0039 
0040 class kpDocument;
0041 class kpView;
0042 class kpMainWindow;
0043 class kpTempImage;
0044 
0045 
0046 class kpViewManager : public QObject
0047 {
0048 Q_OBJECT
0049 
0050 public:
0051     explicit kpViewManager (kpMainWindow *mainWindow);
0052     ~kpViewManager () override;
0053 
0054 
0055 private:
0056     kpDocument *document () const;
0057 
0058 
0059 //
0060 // Registering views
0061 //
0062 
0063 public:
0064     void registerView (kpView *view);
0065     void unregisterView (kpView *view);
0066     void unregisterAllViews ();
0067 
0068 
0069 //
0070 // View
0071 //
0072 
0073 public:
0074     kpView *viewUnderCursor (bool usingQt = false) const;
0075 
0076     //
0077     // QWidget::hasMouse() is unreliable:
0078     //
0079     // "bool QWidget::hasMouse () const
0080     //  ... See the "underMouse" property for details.
0081     //         .
0082     //         .
0083     //         .
0084     //  bool underMouse
0085     //  ... This value is not updated properly during drag and drop operations."
0086     //
0087     // i.e. it's possible that hasMouse() returns false in a mousePressEvent()!
0088     //
0089     // This hack needs to be called from kpView so that viewUnderCursor() works
0090     // as a reasonable replacement (although there is at least one case where
0091     // it still won't work - just after a fake drag onto the view).
0092     //
0093     void setViewUnderCursor (kpView *view);
0094 
0095 
0096 public:
0097     // Returns whether at least 1 view has keyboard focus.
0098     // A pointer is not returned to such a view because more than one can
0099     // have focus at the same time (see QWidget::isActiveWindow()).
0100     bool hasAViewWithFocus () const;
0101 
0102 
0103 //
0104 // Mouse Cursors
0105 //
0106 
0107 public:
0108     void setCursor (const QCursor &cursor);
0109     void unsetCursor ();
0110 
0111 
0112 //
0113 // Temp Image
0114 //
0115 
0116 public:
0117     const kpTempImage *tempImage () const;
0118     void setTempImage (const kpTempImage &tempImage);
0119     void invalidateTempImage ();
0120 
0121 
0122 //
0123 // Selections
0124 //
0125 
0126 public:
0127     bool selectionBorderVisible () const;
0128     void setSelectionBorderVisible (bool yes = true);
0129 
0130     bool selectionBorderFinished () const;
0131     void setSelectionBorderFinished (bool yes = true);
0132 
0133 
0134 //
0135 // Text Cursor
0136 //
0137 
0138 public:
0139     // If you enable the text cursor, a timer will start ticking to update
0140     // the text cursor.  If no text selection is active, the update will
0141     // be a NOP but the timer will still tick and textCursorEnabled() will
0142     // still return true.
0143     bool textCursorEnabled () const;
0144     void setTextCursorEnabled (bool yes = true);
0145 
0146     bool textCursorBlinkState () const;
0147     void setTextCursorBlinkState (bool on = true);
0148 
0149     // By convention, a text box with no content (i.e. no text lines) should
0150     // have a cursor position of (row=0,col=0).  Some code assumes this.
0151     //
0152     // (no error checking is performed - the row and col are as per
0153     //  setTextCursorPosition() so may be out of the bounds of the
0154     //  text selection)
0155     int textCursorRow () const;
0156     int textCursorCol () const;
0157     // See kpToolText::beginDrawSelectText() for a correct use of this
0158     // method, satisfying the above convention.
0159     //
0160     // WARNING: If the previous row and column are invalid (e.g. you just
0161     //          called kpTextSelection::setTextLines() such that the previous
0162     //          row and column now point outside the lines), this will not
0163     //          be able to erase the cursor at the old position.
0164     //
0165     //          Always ensure that the text cursor position is valid.
0166     //          TODO: We need to check this in all source files.
0167     //                e.g. It's definitely wrong for kpToolTextBackspaceCommand.
0168     void setTextCursorPosition (int row, int col);
0169 
0170     // Returns the document rectangle where cursor would be placed, using
0171     // textCursorRow() and textCursorCol ().
0172     //
0173     // For a text selection without any content, this returns a rectangle
0174     // corresponding to the first text row and column.
0175     //
0176     // If there is no text selection or textCursorRow() or
0177     // textCursorCol() are invalid, it returns an empty rectangle.
0178     QRect textCursorRect () const;
0179 
0180 protected:
0181     // If textCursorRect() is valid, updates all views at that rectangle.
0182     // The cursor blink state and timer are not affected at all.
0183     // TODO: This and other methods will happily execute even if
0184     //       !textCursorEnabled().  We should fix this.
0185     void updateTextCursor ();
0186 
0187 protected Q_SLOTS:
0188     void slotTextCursorBlink ();
0189 
0190 
0191 //
0192 // View Updates
0193 //
0194 
0195 public:
0196     // Specifies whether to queue _all_ paint events
0197     // (generated by you or the window system), until the
0198     // corresponding call to restoreQueueUpdates().  Use this
0199     // before multiple, big, non-interactive changes to the
0200     // document to eliminate virtually all flicker.
0201     //
0202     // This is better than QWidget::setUpdatesEnabled() because
0203     // restoreQueueUpdates() automatically restores, for each view,
0204     // only the _regions_ that need to be repainted.
0205     //
0206     // You can nest blocks of setQueueUpdates()/restoreQueueUpdates().
0207     bool queueUpdates () const;
0208     void setQueueUpdates ();
0209     void restoreQueueUpdates ();
0210 
0211 public:
0212     // Controls behaviour of updateViews():
0213     //
0214     // Slow: Let Qt buffer paint events via QWidget::update().
0215     //       Results in less flicker.  Paint events are probably merged
0216     //       so long-term efficiency is increased at the expense of
0217     //       reduced responsiveness (default).  Generally, the paint
0218     //       event happens a while later -- when you return to the event
0219     //       loop.
0220     // Fast: Force Qt to redraw immediately.  No paint events
0221     //       are merged so there is great potential for flicker,
0222     //       if used inappropriately.  Use this when the redraw
0223     //       area is small and responsiveness is critical.
0224     //       Continual use of this mode can result in
0225     //       unnecessary redraws and incredibly slugish performance.
0226     //
0227     // You can nest blocks of setFastUpdates()/restoreFastUpdates().
0228     bool fastUpdates () const;
0229     void setFastUpdates ();
0230     void restoreFastUpdates ();
0231 
0232 public Q_SLOTS:
0233     void updateView (kpView *v);
0234     void updateView (kpView *v, const QRect &viewRect);
0235     void updateView (kpView *v, int x, int y, int w, int h);
0236     void updateView (kpView *v, const QRegion &viewRegion);
0237 
0238     void updateViewRectangleEdges (kpView *v, const QRect &viewRect);
0239 
0240     void updateViews (const QRect &docRect);
0241 
0242 
0243 public Q_SLOTS:
0244     void adjustViewsToEnvironment ();
0245 
0246 public Q_SLOTS:
0247     void setInputMethodEnabled (bool inputMethodEnabled);
0248 
0249 private:
0250     struct kpViewManagerPrivate * const d;
0251 };
0252 
0253 
0254 #endif  // KP_VIEW_MANAGER_H