~ubuntu-branches/ubuntu/hardy/qgis/hardy

« back to all changes in this revision

Viewing changes to src/legend/qgslegend.h

  • Committer: Bazaar Package Importer
  • Author(s): William Grant
  • Date: 2007-05-06 13:42:32 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20070506134232-pyli6t388w5asd8x
Tags: 0.8.0-3ubuntu1
* Merge from Debian unstable. Remaining Ubuntu changes:
  - debian/rules, debian/qgis.install, debian/qgis.dirs debian/qgis.desktop:
    Add and install .desktop.
* debian/qgis.desktop: Remove Applications category; it's not real.
* Modify Maintainer value to match Debian-Maintainer-Field Spec

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************
 
2
                          qgslegend.h  -  description
 
3
                             -------------------
 
4
    begin                : Sun Jul 28 2002
 
5
    copyright            : (C) 2002 by Gary E.Sherman
 
6
    email                : sherman at mrcc dot com
 
7
               Romans 3:23=>Romans 6:23=>Romans 10:9,10=>Romans 12
 
8
 ***************************************************************************/
 
9
 
 
10
/***************************************************************************
 
11
 *                                                                         *
 
12
 *   This program is free software; you can redistribute it and/or modify  *
 
13
 *   it under the terms of the GNU General Public License as published by  *
 
14
 *   the Free Software Foundation; either version 2 of the License, or     *
 
15
 *   (at your option) any later version.                                   *
 
16
 *                                                                         *
 
17
 ***************************************************************************/
 
18
/* $Id: qgslegend.h 6249 2006-12-13 10:28:01Z mhugent $ */
 
19
 
 
20
#ifndef QGSLEGEND_H
 
21
#define QGSLEGEND_H
 
22
 
 
23
#include <deque>
 
24
#include <map>
 
25
#include <set>
 
26
#include <QTreeWidget>
 
27
 
 
28
class QgisApp;
 
29
class QgsLegendLayer;
 
30
class QgsLegendLayerFile;
 
31
class QgsLegendItem;
 
32
class QgsMapLayer;
 
33
class QgsMapCanvas;
 
34
class QDomDocument;
 
35
class QDomNode;
 
36
class QMouseEvent;
 
37
class QTreeWidgetItem;
 
38
 
 
39
/**
 
40
   \class QgsLegend
 
41
   \brief A Legend treeview for QGIS
 
42
   Map legend is a specialised QListView designed to show grooups of map layers,
 
43
   map layers, and the map layer members, properties and symbols for each layer.
 
44
 
 
45
   The legend supports simple operations such as displaying an ordered list of 
 
46
   layers in the current canvas, and complex operations such as drag/dropping 
 
47
   layer symbologies and properties between layers. 
 
48
 
 
49
   There are a variety of different items that can appear in a QgsLegend. All 
 
50
   items added to a QgsLegend should be inherited from QgsLegendItem as this
 
51
   will ensure that they can perform legend specific tasks such as seeing if
 
52
   dropping of other items onto them is allowed, returning their type etc.
 
53
 
 
54
   The following types are defined:
 
55
   <ul>
 
56
   <li>QgsLegendGroup - a group folder for many layers (can include other groups)</li>
 
57
   <li>QgsLegendLayer - a layer that contains one or more files associated with it. 
 
58
                        allowing more than one file lets you create virtual layers where
 
59
                        1 or more files can share the same symbology and properties
 
60
                        and be treated as they are one layer for things such as hiding / 
 
61
                        showing, scale dependent visibility etc.</li>
 
62
   <li>QgsLegendSymbologyGroup - a collabsable node that contains symbology items. Can
 
63
                                only exist inside of a QgsLegendLayer</li>
 
64
   <li>QgsLegendSymbologyItem - a class break (vector) or pallette entry (raster) etc. 
 
65
                                Double clicking on a symbology item will let you change
 
66
                                the properties for only that specific item. Can only exist
 
67
                                inside a symbology group.</li>
 
68
   <li>QgsLegendPropertyGroup - a collapsable node that shows 1 or more properties. Can
 
69
                                only exist inside of a QgsLegendLayer</li>
 
70
   <li>QgsLegendPropertyItem - A list of properties related to the layer. Double clicking
 
71
                              a property item will invoke a dialog that will let you change
 
72
                              the property settings. Can only exist inside a property group</li>
 
73
   <li>QgsLegendLayerFileGroup - each QgsLegendLayer can have one or more files associated
 
74
                              with it. This is the container group for these files. Can
 
75
                              only exist inside of a QgsLegendLayer.</li>
 
76
   <li>QgsLegendLayerFile -  A file node that relates to a file on disk. Assigning multiple
 
77
                             file nodes in a file group allows you treat them as if they are
 
78
                             one entity.</li>
 
79
   </ul>
 
80
   @note Additional group types may be defined in the future to accommodate WMS, PostGIS etc layers.
 
81
   @author Gary E.Sherman, Tim Sutton, Marco Hugentobler and Jens Oberender
 
82
*/
 
83
 
 
84
class QgsLegend : public QTreeWidget
 
85
{
 
86
    Q_OBJECT;
 
87
        
 
88
 public:
 
89
    /*! Constructor.
 
90
   * @param qgis_app link to qgisapp   
 
91
   * @param theParent An optional parent widget
 
92
   * @param theName An optional name for the widget
 
93
   */
 
94
  QgsLegend(QgisApp* app, QWidget * parent = 0, const char *name = 0);
 
95
 
 
96
  //! Destructor
 
97
   ~QgsLegend();
 
98
 
 
99
  /*!Returns the current layer if the current item is a QgsLegendLayerFile.
 
100
   If the current item is a QgsLegendLayer, its first maplayer is returned.
 
101
  Else, 0 is returned.*/
 
102
  QgsMapLayer* currentLayer();
 
103
 
 
104
  /**Writes the content of the legend to a project file*/
 
105
  bool writeXML(QDomNode & layer_node, QDomDocument & document);
 
106
 
 
107
  /**Restores the legend from a project file*/
 
108
  bool readXML(QDomNode& legendnode);
 
109
 
 
110
  /**Returns true, if the y-coordinate is >= the center of the item*/
 
111
  bool yCoordAboveCenter(QgsLegendItem* it, int ycoord);
 
112
 
 
113
  /**Returns the first item in the hierarchy*/
 
114
  QTreeWidgetItem* firstItem();
 
115
 
 
116
  /**Returns the next item (next sibling or next item on level above)*/
 
117
  QTreeWidgetItem* nextItem(QTreeWidgetItem* item);
 
118
 
 
119
  /**Returns the next sibling of an item or 0 if there is none*/
 
120
  QTreeWidgetItem* nextSibling(QTreeWidgetItem* item);
 
121
 
 
122
  /**Returns the previous sibling of an item or 0 if there is none*/
 
123
  QTreeWidgetItem* previousSibling(QTreeWidgetItem* item);
 
124
 
 
125
  /**Finds the next dom node. This function is used by QgsLegend, but probably its not a good place here*/
 
126
  static QDomNode nextDomNode(const QDomNode& theNode);
 
127
 
 
128
  /**Inserts an item into another one. Stores the item specific settings of the moved item (and its subitems)
 
129
   and applies it afterwards again*/
 
130
  void insertItem(QTreeWidgetItem* move, QTreeWidgetItem* into);
 
131
 
 
132
  /**Moves an item after another one. Stores the item specific settings of the moved item (and its subitems)
 
133
   and applies it afterwards again*/
 
134
  void moveItem(QTreeWidgetItem* move, QTreeWidgetItem* after);
 
135
 
 
136
  /**Removes an item from the legend. This is e.g. necessary before shifting it to another place*/
 
137
  void removeItem(QTreeWidgetItem* item);
 
138
 
 
139
  /**Returns the ids of the layers contained in this legend. The order is bottom->top*/
 
140
  std::deque<QString> layerIDs();
 
141
  
 
142
  /**Updates layer set of map canvas*/
 
143
  void updateMapCanvasLayerSet();
 
144
 
 
145
  /**Removes the symbology items of a layer and adds new ones. If other files are in the same legend layer, the new symbology settings are copied.
 
146
   Note: the QIcon* are deleted and therefore need to be allocated by calling functions using operator new*/
 
147
  void changeSymbologySettings(const QString& key, const std::list< std::pair<QString, QPixmap> >* newSymbologyItems);
 
148
  
 
149
  /**Adds an entry to mPixmapWidthValues*/
 
150
  void addPixmapWidthValue(int width);
 
151
 
 
152
  /**Adds an entry to mPixmapHeightValues*/
 
153
  void addPixmapHeightValue(int height);
 
154
 
 
155
  /**Removes an entry from mPixmapWidthValues*/
 
156
  void removePixmapWidthValue(int width);
 
157
 
 
158
  /**Removes an entry from mPixmapHeightValues*/
 
159
  void removePixmapHeightValue(int height);
 
160
 
 
161
  /** Sets the name of the QgsLegendLayer that is the parent of 
 
162
      the given QgsLegendLayerFile */
 
163
  void setName(QgsLegendLayerFile* w, QString layerName);
 
164
 
 
165
  void updateCheckStates(QTreeWidgetItem* item, Qt::CheckState state) {mStateOfCheckBoxes[item] = state;}
 
166
 
 
167
public slots:
 
168
 
 
169
    /*!Adds a new layer group with the maplayer to the canvas*/
 
170
    void addLayer( QgsMapLayer * layer );
 
171
 
 
172
    void setMapCanvas(QgsMapCanvas * canvas){mMapCanvas = canvas;}
 
173
 
 
174
 /*!
 
175
   * Slot called to clear the tree of all items
 
176
   * @note Usually connected to a QgsMapCanvas that will ask its legend to clear itself.
 
177
   * @return void
 
178
   */
 
179
  void removeAll();
 
180
 
 
181
  /*!
 
182
   * Called when the user wishes to toggle on or off all of the layers in
 
183
   * the legend, and in the map.
 
184
   * @return void
 
185
   */
 
186
  void selectAll(bool select);
 
187
 
 
188
  /*!
 
189
   * Slot called when user wishes to add a new empty layer group to the legend.
 
190
   * The user will be prompted for the name of the newly added group.
 
191
   * @return void
 
192
   */
 
193
  void addGroup();
 
194
  void removeLayer(QString);
 
195
 
 
196
  /**Removes the current LegendLayer and all its LegendLayerFiles*/
 
197
  void legendLayerRemove();
 
198
 
 
199
protected:
 
200
 
 
201
  /*!Event handler for mouse movements.
 
202
   * Mainly intended so handle cases where user is dragging and dropping
 
203
   * items into or out of groups, or is reordering layers.
 
204
   * @note Overrides method of the same name in the QListView class.
 
205
   * @return void
 
206
   */ 
 
207
  void mouseMoveEvent(QMouseEvent * e);
 
208
 
 
209
  /*!
 
210
   * Event handler for buton mouse presses.
 
211
   * Mainly intended so handle cases where user is dragging and dropping
 
212
   * items into or out of groups, or is reordering layers.
 
213
   * @note Overrides method of the same name in the QListView class.
 
214
   * @return void
 
215
   */ 
 
216
  void mousePressEvent(QMouseEvent * e);
 
217
 
 
218
  /*!
 
219
   * Event handler for mouse button releases.
 
220
   * Mainly intended so handle cases where user is dragging and dropping
 
221
   * items into or out of groups, or is reordering layers. Each sublass of
 
222
   * QgsLegendItem has an accept method that defines behaviour rules for
 
223
   * whether another QgsLegendItem child instance can be dropped onto it.
 
224
   * <h1>Behaviour rules for dropped legend items</h1>
 
225
   * <ul>
 
226
   * <li> Symbology groups, properies groups and layers groups can only be dropped
 
227
   * onto QgsLegendLayer nodes. </li> 
 
228
   * <li>Only QgsLegendGroup and QgsLegendLayer can be top level items in the view</li>
 
229
   * <li>Groups can be nested by dropping them into each other,</li>
 
230
   * <li>Each group can have one or more layers</li>
 
231
   * <li>Layers can be ordered by dragging them above or below another layer.</li>
 
232
   * <li>The order for QgsLegendSymbologyGroup, QgsLegendPropertyGroup and QgsLegendLayerGroup
 
233
   * is predefined to sort in that order.</li>
 
234
   * </ul>
 
235
   * @note Overrides method of the same name in the QListView class.
 
236
   * @return void
 
237
   */  
 
238
  void mouseReleaseEvent(QMouseEvent * e);
 
239
  void mouseDoubleClickEvent(QMouseEvent* e);
 
240
 
 
241
    /**Stores the necessary information about the position of an item in the hierarchy. Afterwards, 
 
242
this item may be moved back to the original position with resetToInitialPosition()*/
 
243
  void storeInitialPosition(QTreeWidgetItem* li);
 
244
  
 
245
  /**Moves an item back to the position where storeInitialPosition has been called*/
 
246
  void resetToInitialPosition(QTreeWidgetItem* li);
 
247
 
 
248
  /**Returns the legend layer to which a map layer gelongs*/
 
249
  QgsLegendLayer* findLegendLayer(const QString& layerKey);
 
250
 
 
251
  /**Checks mPixmapWidthValues and mPixmapHeightValues and sets a new icon size if necessary*/
 
252
  void adjustIconSize();
 
253
 
 
254
  /**This function compares the layer order before a drag with the current layer ordering and triggers a canvas repaint if it has changed*/
 
255
  bool checkLayerOrderUpdate();
 
256
 
 
257
  private slots:
 
258
 
 
259
  /**Calls 'handleRightClickEvent' on the item*/
 
260
  void handleRightClickEvent(QTreeWidgetItem* item, const QPoint& position);
 
261
  /**Removes the current legend group*/
 
262
  void legendGroupRemove();
 
263
  /**Adds all the legend layer files of the current legend layer to overview*/
 
264
  void legendLayerAddToOverview();
 
265
  /**Removes all the legend layer files of the current legend layer from overview*/
 
266
  void legendLayerRemoveFromOverview();
 
267
  /**Shows the property dialog of the first legend layer file in a legend layer*/
 
268
  void legendLayerShowProperties();
 
269
  /**Toggles the editing mode of the first layer file of a legend layer*/
 
270
  void legendLayerToggleEditing();
 
271
  /**Saves the current layer to shapefile (if the provider supports it)*/
 
272
  void legendLayerSaveAsShapefile();
 
273
   /**Sets all listview items to open*/
 
274
  void expandAll();
 
275
  /**Sets all listview items to closed*/
 
276
  void collapseAll();
 
277
  /**Just for a test*/
 
278
  void handleItemChange(QTreeWidgetItem* item, int row);
 
279
  /** delegates current layer to map canvas */
 
280
  void handleCurrentItemChanged(QTreeWidgetItem* current, QTreeWidgetItem* previous);
 
281
  /**Calls openPersistentEditor for the current item*/
 
282
  void openEditor();
 
283
  /**Removes the current item and inserts it as a toplevel item at the end of the legend*/
 
284
  void makeToTopLevelItem();
 
285
  /**Show/ Hide the legend layer file groups*/
 
286
  void showLegendLayerFileGroups();
 
287
  /**Zooms to extent of the current legend layer (considers there may be several
 
288
   legend layer files*/
 
289
  void zoomToLayerExtent();
 
290
 
 
291
private:
 
292
 
 
293
  /**Pointer to QGisApp, needed for signal/slot reasons*/
 
294
  QgisApp* mApp;
 
295
 
 
296
   /*! Prevent the copying of QgsLegends
 
297
   * @todo See if this is really required - we may want multiple map, canvas and 
 
298
           legend support at some stage in the future.
 
299
   */
 
300
  QgsLegend( QgsLegend const & );
 
301
 
 
302
  /*!
 
303
   * Prevent the copying of QgsLegends
 
304
   * @todo See if this is really required - we may want multiple map, canvas and 
 
305
           legend support at some stage in the future.
 
306
   */
 
307
  QgsLegend & operator=( QgsLegend const & );
 
308
 
 
309
  /*!
 
310
   * Position of mouse when it is pressed at the start of a drag event.
 
311
   */
 
312
  QPoint mLastPressPos;
 
313
 
 
314
  /**True if the mouse is pressed*/
 
315
  bool mMousePressedFlag;
 
316
 
 
317
  /// keep track of the Item being dragged
 
318
  QTreeWidgetItem* mItemBeingMoved;
 
319
 
 
320
  /*!
 
321
   * Position in the list of the item being moved as it was at the start of a drag event.
 
322
   * An item at the top of the list will be 0 and each successive item below it
 
323
   * will be 1,2 3 etc... regardless of nesting level.
 
324
   */
 
325
  int mItemBeingMovedOrigPos;
 
326
 
 
327
  /**Information needed by 'storeInitialPosition' and 'resetToInitialPosition'*/
 
328
  enum HIERARCHY_POSITION_TYPE
 
329
    {
 
330
      FIRST_ITEM,
 
331
      FIRST_CHILD,
 
332
      YOUNGER_SIBLING
 
333
    };
 
334
  HIERARCHY_POSITION_TYPE mRestoreInformation;
 
335
  QTreeWidgetItem* mRestoreItem;
 
336
 
 
337
  bool mShowLegendLayerFiles;
 
338
 
 
339
  /**Stores the layer ordering before a mouse Move. After the move, this is used to
 
340
   decide if the mapcanvas really has to be refreshed*/
 
341
  std::deque<QString> mLayersPriorToMove;
 
342
 
 
343
  /*!
 
344
   * A fuction sed to determin how far down in the list an item is (starting with one for the first Item.
 
345
   *If the item is not in the legend, -1 is returned
 
346
   * @see mItemBeingMovedOrigPos
 
347
   */
 
348
  int getItemPos(QTreeWidgetItem* item);
 
349
 
 
350
  /**Pointer to the main canvas. Used for requiring repaints in case of legend changes*/
 
351
  QgsMapCanvas* mMapCanvas;
 
352
 
 
353
  /**Map that keeps track of which checkboxes are in which check state. This is necessary because QTreeView does not emit 
 
354
     a signal for check state changes*/
 
355
  std::map<QTreeWidgetItem*, Qt::CheckState> mStateOfCheckBoxes;
 
356
 
 
357
  /**Stores the width values of the LegendSymbologyItem pixmaps. The purpose of this is that the legend may automatically change
 
358
   the global IconWidth when items are added or removed*/
 
359
  std::multiset<int> mPixmapWidthValues;
 
360
 
 
361
  /**Stores the width values of the LegendSymbologyItem pixmaps. The purpose of this is that the legend may automatically change
 
362
   the global IconWidth when items are added or removed*/
 
363
  std::multiset<int> mPixmapHeightValues;
 
364
 
 
365
  /**QgsLegend does not set the icon with/height to values lower than the minimum icon size*/
 
366
  QSize mMinimumIconSize;
 
367
 
 
368
  /**Stores a pointer to the current map layer. This is used to check when the current layer changes*/
 
369
  QgsMapLayer* mCurrentLayer;
 
370
 
 
371
signals:
 
372
  void zOrderChanged(QgsLegend * lv);
 
373
 
 
374
  //! Emited whenever current (selected) layer changes
 
375
  //  the pointer to layer can be null if no layer is selected
 
376
  void currentLayerChanged ( QgsMapLayer * layer );
 
377
};
 
378
#endif