summaryrefslogtreecommitdiffstats
path: root/lib/kofficeui/KoGuides.h
blob: c1f66138e3e558b5bb7974707384e75bca071dbc (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
// -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4; -*-
/* This file is part of the KDE project
   Copyright (C) 2005 Thorsten Zachmann <zachmann@kde.org>
   Copyright (C) 2005 Casper Boemann Rasmussen <cbr@boemann.dk>

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

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

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

#ifndef KOGUIDES_H
#define KOGUIDES_H

#include <tqevent.h>
#include <tqobject.h>

#include <koffice_export.h>

class TQPaintDevice;
class KoPoint;
class KoRect;
class KoView;
class KoZoomHandler;

class KOFFICEUI_EXPORT KoGuides : public TQObject
{
    Q_OBJECT
  TQ_OBJECT
public:        
    /**
     * @brief Constructor
     *
     * @param view The view in which the guides will be shown
     * @param zoomHandler The zoom handler of the view
     */
    KoGuides( KoView *view, KoZoomHandler *zoomHandler );

    /**
     * @brief Destructor
     */
    ~KoGuides();
        
    /**
     * @brief Paint the guides
     *
     * @param painter with which the guides are painted
     */
    void paintGuides( TQPainter &painter );

    typedef int SnapStatus;
    static const SnapStatus SNAP_NONE, SNAP_HORIZ, SNAP_VERT, SNAP_BOTH;

    /**
     * @brief Handle mousePressEvent
     *
     * This checks if a mousePressEvent would affect a guide line.
     * If the mouse is pressed over a guide line it gets selected.
     * Guide lines which were select get unselect.
     * If also the Ctrl Key is pressed the selection of the guide 
     * gets toggled.
     * If no guide is under the position all guides get deselected.
     *
     * @param e TQMouseEvent
     *
     * @return true if the event was handled
     * @return false otherwise
     *         The event counts a not handled when only guides where
     *         deselected.
     */
    bool mousePressEvent( TQMouseEvent *e );

    /**
     * @brief Handle mouseMoveEvent
     *
     * If the mouse button is pressed and a guide was selected it moves the 
     * selected guides.
     * If the mouse is moved over a guide line the cursor gets updated.
     *
     * @param e TQMouseEvent
     *
     * @return true if the event was handled (guide moved, cursor changed as
     *         guide lies below)    
     * @return false otherwise
     */
    bool mouseMoveEvent( TQMouseEvent *e );
    
    /**
     *
     * @param e TQMouseEvent
     *
     * @return true if the event was handled
     * @return false otherwise
     */
    bool mouseReleaseEvent( TQMouseEvent *e );
    
    /**
     *
     * @param e TQKeyEvent
     *
     * @return true if the event was handled
     * @return false otherwise
     */
    bool keyPressEvent( TQKeyEvent *e );

    /**
     * @brief Set the guide lines.
     *
     * This removes all existing guides and set up new ones at the positions given.
     *
     * @param horizontalPos A list of the position of the horizontal guide lines.
     * @param verticalPos A list of the position of the vertical guide lines.
     */
    void setGuideLines( const TQValueList<double> &horizontalPos, const TQValueList<double> &verticalPos );

    /**
     * @brief Set the positions for snapping of auto guide lines
     *
     * This removes all existing auto guide lines and set up new ones at the positions given.
     *
     * @param horizontalPos A list of the position of the horizontal guide lines.
     * @param verticalPos A list of the position of the vertical guide lines.
     */
    void setAutoGuideLines( const TQValueList<double> &horizontalPos, const TQValueList<double> &verticalPos );

    /**
     * @brief Get the position of the guide lines
     *
     * This filles the passed lists with the positions of the guide lines. 
     * The lists will be emptied before any positions are added.
     *
     * @param horizontalPos A list of the position of the horizontal guide lines.
     * @param verticalPos A list of the position of the vertical guide lines.
     */
    void getGuideLines( TQValueList<double> &horizontalPos, TQValueList<double> &verticalPos ) const;

    /**
     * @brief Snap rect to guidelines
     *
     * This looks for a guide which is in reach for the guide as defined in snap.
     * This method has the abillity to combine more calls. The snapStatus and diff args are both input and
     * output. On first call you should set snapStatus to 0. The return value would then show in which
     * directions it has snapped. If you combine several KoGuides you can let these output arguments
     * be input for the next koGuide. That way you'll always catch the nearest guide.
     *
     * @param rect the rect which should be snapped
     * @param snap the distance within the guide should snap - but always snap if already snapped
     * @param snapStatus if horiz,vert or both directions are snapped (both in and out param). 
     * @param diff distance away from guide. Only valid if status is snapping (both in and out param)
     */
    void snapToGuideLines( KoRect &rect, int snap, SnapStatus &snapStatus, KoPoint &diff );

    /**
     * @brief Snap rect to guidelines
     *
     * This looks fo a guide which is in reach for the guide as defined in snap.
     *
     * @param pos the position which should be snapped
     * @param snap the distance wherein the guide should snap - but always snap if already snapped
     * @param snapStatus if horiz,vert or both directions are snapped (both in and out param)
     * @param diff distance away from guide. Only valid if status is snapping (both in and out param)
     */
    void snapToGuideLines( KoPoint &pos, int snap, SnapStatus &snapStatus, KoPoint &diff );

    /**
     * @brief repaint guides if any changed snapping status
     *
     * This issues a paint request if any guides have changed snapping status.
     *
     * @param snappedRect the rect after it has been snapped
     */
    void repaintSnapping( const KoRect &snappedRect );

    /**
     * @brief repaint guides if any changed snapping status
     *
     * This issues a paint request if any guides have changed snapping status.
     *
     * @param snappedPoint the point after it has been snapped
     */
    void repaintSnapping( const KoPoint &snappedPoint, SnapStatus snapStatus );

    /**
     * @brief repaint guides so none is snapped
     *
     * This issues a paint request if any guides have changed snapping status.
     * It also effectively un-snaps all since it doesn't take an argument 
     */
    void repaintAfterSnapping( );

    /**
     * @brief Find the closesed disance to the next guide within the given distance
     *
     * @param rect The rect which should be snapped
     * @param diff distance in which too look for the closesed guide. The parameter is updated
     * with the closesed distance to a guide if one is found (both in and out param)
     */
    void diffNextGuide( KoRect &rect, KoPoint &diff );

public slots:
    /**
     * @brief Move Guide
     *
     * This slot can be connected to void KoRuler::moveGuide( const TQPoint &, bool, int );
     * It will add a new guide when you move from the ruler to the canvas. After that it
     * moves the guide.
     *
     * @param pos The pos of the mouse 
     * @param horizontal true if the guide is horizontal, false if vertical
     * @param rulerWidth The witdth of the ruler as the pos is seen from the ruler widget.
     */
    void moveGuide( const TQPoint &pos, bool horizontal, int rulerWidth );

    /**
     * @brief Add Guide
     *
     * This slot can be connected to void KoRuler::addGuide( const TQPoint &, bool, int );
     * It will finish the inserting of a guide from moveGuide().
     *
     * @param pos The pos of the mouse 
     * @param horizontal true if the guide is horizontal, false if vertical
     * @param rulerWidth The witdth of the ruler as the pos is seen from the ruler widget.
     */
    void addGuide( const TQPoint &pos, bool horizontal, int rulerWidth );

signals:
    /**
     * @brief Signal that shows that the guide lines are changed
     *
     * This signal is emmited when the guide lines are changed ( moved / deleted )
     *
     * @param view The view in which the guide lines are changed.
     */
    void guideLinesChanged( KoView * view );

    /**
     * @brief This signal is emitted when guides start/stop moving.
     *
     * @param state true when starting moving guides, false when stopping.
     */
    void moveGuides( bool state );

    /**
     * @brief This signal is emitted when guides start/stop painting.
     *
     * With this signal it is possible to only repaint the guides in the paint 
     * method of the canvas. Just set/unset a flag when this signal is emmited.
     * This signal is emitted before and after a repaint is done.
     *
     * @param state true when starting painting guides, false when stopping.
     */
    void paintGuides( bool state );

private slots:
    /**
     * @brief Execute a dialog to set the position of the guide
     */
    void slotChangePosition();

    /**
     * @brief remove all selected guides
     */
    void slotRemove();

private:
    /// Strukt holding the data of a guide line
    struct KoGuideLine 
    {
        KoGuideLine( Qt::Orientation o, double pos, bool a = false )
        : orientation( o )
        , position( pos )
        , selected( false )
        , snapping( false )
        , automatic( a )
        {}
        Qt::Orientation orientation;
        double position;
        bool selected; // if this guide is selected
        bool snapping; // if this guide is being snapped to
        bool automatic; // if this is a atomatic guide line
    };

    /**
     * @brief Paint the canvas
     */ 
    void paint();

    /**
     * @brief Add a guide line with the orientation o at the position pos
     *
     * @param pos where to insert the guide
     * @param o orientation of the guide line
     */
    void add( Qt::Orientation o, TQPoint &pos );
    
    /**
     * @brief Select a guide
     *
     * @param gd guide to select
     */
    void select( KoGuideLine *guideLine );

    /**
     * @brief Unselect a guide
     *
     * @param gd guide to unselect
     */
    void unselect( KoGuideLine *guideLine );
        
    /**
     * @brief Unselect all selected KoGuideLineData
     *
     * @return true, when selection was changed
     * @return false otherwise
     */
    bool unselectAll();

    /**
     * @brief remove all selected guides
     */
    void removeSelected();

    /**
     * @brief Check if at least one guide is selected
     *
     * @return true if at least on guide is seleted
     * @return false otherwise
     */
    bool hasSelected();

    /**
     * @brief Find a guide
     *
     * This function looks for a guide at x or y pos. The position can differ by
     * diff.
     *
     * @param x x position to look for a guide
     * @param y y position to look for a guide
     * @param diff how far next to a guide sould it also be found
     *
     * @return the fould guide
     * @return 0 if none is found
     */
    KoGuideLine * find( KoPoint &p, double diff );

    /**
     * @brief Move selected guides.
     *
     * This moves all selected guides around. If more than one guide is selected it makes
     * sure the guides are not moved of the canvas.
     *
     * @param pos position of the mouse
     */
    void moveSelectedBy( TQPoint &p );

    /**
     * @brief Map pos from screen
     * 
     * @param pos on screen
     *
     * @return pos in document
     */
    KoPoint mapFromScreen( const TQPoint & pos );

    /**
     * @brief Map pos to screen
     * 
     * @param pos in document
     *
     * @return pos on screen
     */
    TQPoint mapToScreen( const KoPoint & pos );

    /**
     * @brief Check if the both values are nearly the same.
     *
     * @param a first value
     * @param a second value
     *
     * @return true if they are the same
     * @return false otherwise
     */ 
    bool virtuallyEqual( double a, double b ) { return TQABS( a - b ) < 1E-4; }

    /// view
    KoView * m_view;
    /// zoom handler of the view
    KoZoomHandler * m_zoomHandler;

    enum GuideLineType
    {
        GL,
        GL_SELECTED, 
        GL_AUTOMATIC,
        GL_END
    };

    /// array of list of the different guide line types
    TQValueList<KoGuideLine *> m_guideLines[GL_END];
    
    /// used to save the last mouse position
    TQPoint m_lastPoint;
    /// true if a guide is selected at the moment
    bool m_mouseSelected;
    /// true if a guide is inserted at the moment
    bool m_insertGuide;
    /// popup menu
    class Popup;
    Popup * m_popup;
};

#endif /* KOGUIDES_H */