📄 qgslegend.cpp
字号:
/*************************************************************************** qgslegend.cpp - description ------------------- begin : Sun Jul 28 2002 copyright : (C) 2002 by Gary E.Sherman email : sherman at mrcc dot com Romans 3:23=>Romans 6:23=>Romans 10:9,10=>Romans 12 ***************************************************************************//*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************//* $Id: qgslegend.cpp 7984 2008-01-16 20:07:55Z wonder $ */#include "qgsapplication.h"#include "qgslogger.h"#include "qgslegend.h"#include "qgslegendgroup.h"#include "qgslegendlayer.h"#include "qgslegendpropertygroup.h"#include "qgslegendsymbologyitem.h"#include "qgslegendlayerfile.h"#include "qgslegendlayerfilegroup.h"#include "qgsmapcanvas.h"#include "qgsmaplayer.h"#include "qgsmaplayerregistry.h"#include "qgsmaprender.h"#include "qgsproject.h"#include "qgsrasterlayer.h"#include "qgsrasterlayerproperties.h"#include "qgsvectorlayer.h"#include "qgsvectorlayerproperties.h"#include "qgsvectordataprovider.h"#include <cfloat>#include <iostream>#include <QFont>#include <QDomDocument>#include <QHeaderView>#include <QMenu>#include <QMessageBox>#include <QMouseEvent>#include <QPixmap>#include <QTreeWidgetItem>static const char *const ident_ = "$Id: qgslegend.cpp 7984 2008-01-16 20:07:55Z wonder $";const int AUTOSCROLL_MARGIN = 16;/** @note set mItemBeingMoved pointer to 0 to prevent SuSE 9.0 crash*/QgsLegend::QgsLegend(QWidget * parent, const char *name) : QTreeWidget(parent), mMousePressedFlag(false), mItemBeingMoved(0), mShowLegendLayerFiles(false), mToggleEditingAction(0), mMapCanvas(0), mMinimumIconSize(20, 20){ connect( this, SIGNAL(itemChanged(QTreeWidgetItem*, int)), this, SLOT(handleItemChange(QTreeWidgetItem*, int))); connect( this, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)), this, SLOT(handleCurrentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*))); // project handling connect(QgsProject::instance(), SIGNAL(readProject(const QDomDocument &)), this, SLOT(readProject(const QDomDocument &))); connect(QgsProject::instance(), SIGNAL(writeProject(QDomDocument &)), this, SLOT(writeProject(QDomDocument &))); setSortingEnabled(false); setDragEnabled(false); setAutoScroll(true); QFont f("Arial", 10, QFont::Normal); setFont(f); setBackgroundColor(QColor(192, 192, 192)); setColumnCount(1); header()->setHidden(1); setRootIsDecorated(true); initPixmaps();}QgsLegend::~QgsLegend(){}void QgsLegend::handleCurrentItemChanged(QTreeWidgetItem* current, QTreeWidgetItem* previous){ QgsMapLayer *layer = currentLayer(); if(mMapCanvas) { mMapCanvas->setCurrentLayer( layer ); } emit currentLayerChanged ( layer );} void QgsLegend::addGroup(){ QgsLegendGroup* group = new QgsLegendGroup(this, tr("group")); mStateOfCheckBoxes.insert(std::make_pair(group, Qt::Checked)); //insert the check state into the map to query for changes later setExpanded(indexFromItem(group), true);}void QgsLegend::removeAll(){ mStateOfCheckBoxes.clear(); clear(); mPixmapWidthValues.clear(); mPixmapHeightValues.clear(); updateMapCanvasLayerSet(); setIconSize(mMinimumIconSize);}void QgsLegend::selectAll(bool select){ if(!mMapCanvas || mMapCanvas->isDrawing()) { return; } QTreeWidgetItem* theItem = firstItem(); while (theItem) { QgsLegendItem* litem = dynamic_cast<QgsLegendItem*>(theItem); if(litem && litem->type() == QgsLegendItem::LEGEND_LAYER_FILE) { theItem->setCheckState(0, (select ? Qt::Checked : Qt::Unchecked)); handleItemChange(theItem, 0); } theItem = nextItem(theItem); }}void QgsLegend::removeLayer(QString layer_key){ if(!mMapCanvas || mMapCanvas->isDrawing()) { return; } QTreeWidgetItem* theItem = firstItem();#ifdef QGISDEBUG qWarning("in QgsLegend::removeLayer");#endif while(theItem) { QgsLegendItem *li = dynamic_cast<QgsLegendItem*>(theItem); if(li) { QgsLegendLayerFile* llf = dynamic_cast<QgsLegendLayerFile*>(li); if(llf) { if (llf->layer()&&llf->layer()->getLayerID() == layer_key) { //remove the map entry for the checkbox mStateOfCheckBoxes.erase(llf); removeItem(llf); delete llf; break; } } } theItem = nextItem(theItem); } updateMapCanvasLayerSet(); adjustIconSize();}void QgsLegend::mousePressEvent(QMouseEvent * e){ if (e->button() == Qt::LeftButton) { mLastPressPos = e->pos(); mMousePressedFlag = true; } else if(e->button() == Qt::RightButton) { QTreeWidgetItem* item = itemAt(e->pos()); setCurrentItem(item); handleRightClickEvent(item, e->globalPos()); } QTreeWidget::mousePressEvent(e);} // contentsMousePressEventvoid QgsLegend::mouseMoveEvent(QMouseEvent * e){ if(mMousePressedFlag) { //set the flag back such that the else if(mItemBeingMoved) //code part is passed during the next mouse moves mMousePressedFlag = false; // remember item we've pressed as the one being moved // and where it was originally QTreeWidgetItem* item = itemAt(mLastPressPos); if(item) { mItemBeingMoved = item; mItemBeingMovedOrigPos = getItemPos(mItemBeingMoved); //store information to insert the item back to the original position storeInitialPosition(mItemBeingMoved); setCursor(Qt::SizeVerCursor); } } else if (mItemBeingMoved) { QPoint p(e->pos()); mLastPressPos=p; // change the cursor appropriate to if drop is allowed QTreeWidgetItem* item = itemAt(p); QgsLegendItem* origin = dynamic_cast<QgsLegendItem*>(mItemBeingMoved); QgsLegendItem* dest = dynamic_cast<QgsLegendItem*>(item); if (item && (item != mItemBeingMoved)) { QgsLegendItem::DRAG_ACTION action = dest->accept(origin); if(action == QgsLegendItem::REORDER) {#ifdef QGISDEBUG qWarning("mouseMoveEvent::REORDER");#endif if(!yCoordAboveCenter(dest, e->y())) //over bottom of item { if(origin->nextSibling() != dest) { if(origin->parent() != dest->parent()) { moveItem(origin, dest); moveItem(dest, origin); } else { moveItem(dest, origin); } } } else //over top of item { if (mItemBeingMoved != dest->nextSibling()) { //origin->moveItem(dest); moveItem(origin, dest); } } setCurrentItem(origin); } else if(action == QgsLegendItem::INSERT) {#ifdef QGISDEBUG qWarning("mouseMoveEvent::INSERT");#endif setCursor( QCursor(Qt::PointingHandCursor) ); if(origin->parent() != dest) { insertItem(origin, dest); setCurrentItem(origin); } } else//no action {#ifdef QGISDEBUG qWarning("mouseMoveEvent::NO_ACTION");#endif if(origin->type() == QgsLegendItem::LEGEND_LAYER_FILE && mItemBeingMovedOrigPos != getItemPos(mItemBeingMoved)) { resetToInitialPosition(mItemBeingMoved); } setCursor( QCursor(Qt::ForbiddenCursor) ); } } }}void QgsLegend::mouseReleaseEvent(QMouseEvent * e){ QTreeWidget::mouseReleaseEvent(e); setCursor(QCursor(Qt::ArrowCursor)); mMousePressedFlag = false; if (!mItemBeingMoved) { return; } QTreeWidgetItem *destItem = itemAt(e->pos()); QgsLegendItem* origin = dynamic_cast<QgsLegendItem*>(mItemBeingMoved); QgsLegendItem* dest = dynamic_cast<QgsLegendItem*>(destItem); // no change? if(!dest || !origin) { checkLayerOrderUpdate(); return; } QgsLegendItem::LEGEND_ITEM_TYPE originType = origin->type(); QgsLegendItem::LEGEND_ITEM_TYPE destType = dest->type(); if(originType == QgsLegendItem::LEGEND_LAYER_FILE && destType == QgsLegendItem::LEGEND_LAYER_FILE_GROUP) { QgsDebugMsg("Legend layer file moved to layer file group"); // Not used... delete? //QgsMapLayer* origLayer = ((QgsLegendLayerFile*)(origin))->layer(); if(dest->childCount() > 1) { //find the first layer in the legend layer group != origLayer and copy its settings QgsLegendItem* currentItem = dynamic_cast<QgsLegendItem*>(dest->child(0)); while(currentItem) { if(currentItem != origin) { QgsMapLayer* origLayer = ((QgsLegendLayerFile*)(origin))->layer(); QgsMapLayer* currentLayer = ((QgsLegendLayerFile*)(currentItem))->layer(); origLayer->copySymbologySettings(*currentLayer); break; } currentItem = currentItem->nextSibling(); } } } else if(originType == QgsLegendItem::LEGEND_LAYER_FILE && destType == QgsLegendItem::LEGEND_LAYER_FILE) { QgsDebugMsg("Legend layer file moved to legend layer file"); // Not used. Delete? // QgsMapLayer* origLayer = ((QgsLegendLayerFile*)(origin))->layer(); // QgsMapLayer* destLayer = ((QgsLegendLayerFile*)(dest))->layer(); if(dest == origin)//origin item has been moved in mouseMoveEvent such that it is under the mouse cursor now { if(origin->parent()->childCount() > 1) { //find the first layer in the legend layer group != origLayer and copy its settings QTreeWidgetItem* currentItem = dest->parent()->child(0); while(currentItem) { if(currentItem != origin) { QgsMapLayer* origLayer = ((QgsLegendLayerFile*)(origin))->layer(); QgsMapLayer* currentLayer = ((QgsLegendLayerFile*)(currentItem))->layer(); origLayer->copySymbologySettings(*currentLayer); break; } currentItem = dynamic_cast<QgsLegendItem*>(currentItem)->nextSibling(); } } } else { QgsMapLayer* origLayer = ((QgsLegendLayerFile*)(origin))->layer(); QgsMapLayer* destLayer = ((QgsLegendLayerFile*)(dest))->layer(); origLayer->copySymbologySettings(*destLayer); } } else { QgsDebugMsg("Other type of drag'n'drop happened!"); } checkLayerOrderUpdate(); mItemBeingMoved = NULL;}void QgsLegend::mouseDoubleClickEvent(QMouseEvent* e){ if(!mMapCanvas || mMapCanvas->isDrawing()) { return; } legendLayerShowProperties();}void QgsLegend::handleRightClickEvent(QTreeWidgetItem* item, const QPoint& position){ if(!mMapCanvas || mMapCanvas->isDrawing()) { return; } QMenu theMenu; QString iconsPath = QgsApplication::themePath(); QgsLegendItem* li = dynamic_cast<QgsLegendItem*>(item); if (li) { if(li->type() == QgsLegendItem::LEGEND_LAYER_FILE) { (static_cast<QgsLegendLayerFile*>(li))->addToPopupMenu(theMenu, mToggleEditingAction); } else if(li->type() == QgsLegendItem::LEGEND_LAYER) { (static_cast<QgsLegendLayer*>(li))->addToPopupMenu(theMenu, mToggleEditingAction); if (li->parent()) { theMenu.addAction(tr("&Make to toplevel item"), this, SLOT(makeToTopLevelItem())); } } else if(li->type() == QgsLegendItem::LEGEND_GROUP) { theMenu.addAction(QPixmap(iconsPath+QString("/mActionRemove.png")), tr("&Remove"), this, SLOT(legendGroupRemove())); } if(li->type() == QgsLegendItem::LEGEND_LAYER || li->type() == QgsLegendItem::LEGEND_GROUP) { theMenu.addAction(tr("Re&name"), this, SLOT(openEditor())); } } theMenu.addAction(QIcon(QPixmap(iconsPath+QString("/folder_new.png"))), tr("&Add group"), this, SLOT(addGroup())); theMenu.addAction(QIcon(QPixmap(iconsPath+QString("/mActionExpandTree.png"))), tr("&Expand all"), this, SLOT(expandAll())); theMenu.addAction(QIcon(QPixmap(iconsPath+QString("/mActionCollapseTree.png"))), tr("&Collapse all"), this, SLOT(collapseAll())); QAction* showFileGroupsAction = theMenu.addAction(tr("Show file groups"), this, SLOT(showLegendLayerFileGroups())); showFileGroupsAction->setCheckable(true); showFileGroupsAction->blockSignals(true); showFileGroupsAction->setChecked(mShowLegendLayerFiles); showFileGroupsAction->blockSignals(false); theMenu.exec(position);}int QgsLegend::getItemPos(QTreeWidgetItem* item){ int counter = 1; QTreeWidgetItem* theItem = firstItem(); while(theItem) { if(theItem == item) { return counter; } theItem = nextItem(theItem); ++counter; } return -1;}void QgsLegend::addLayer( QgsMapLayer * layer ){ if(!mMapCanvas || mMapCanvas->isDrawing()) { return; } QgsLegendLayer * llayer = new QgsLegendLayer(layer->name());//generate entry for mStateOfCheckBoxes below QgsLegendLayerFileGroup * llfgroup = new QgsLegendLayerFileGroup(llayer,QString("Files"));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -