mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-15 00:04:00 -04:00
QgsVectorLayer: - move attribute part of editing to vector layer class and unify with geometry handling: * remove commitAttributeChanges(), addedFeatures(), deletedFeatureIds(), changedAttributes() and replace with changeAttributeValue(), deleteFeature(), addAttribute() and deleteAttribute() * add pendingFields(), pendingAttributeList(), pendingFeatureCount() * emit signals on start editing and commit, change of attribute values, adding/deleting of attributes and layer or feature removal (currently used in the attribute table) - new commitErrors() method to query errors from commitChanges() - replaced featuresInRectangle with select/getNextFeature combo - edit types added to support more input widgets and input constraints QgsFeature: - remove update aware ctor - unify geometry handling in ctors QgsVectorDataProvider: - add QVariant::Type to supportNativeTypes() QgisApp: - add instance() method to query QgisApp object - replace code at various place to use it instead of passing the pointer arround or searching it in the widget tree. - move toggleEditing() code from the legend here QgsAttributeTable/QgsAttributeTableDisplay: - move attribute table creation legend here - make attribute table dockable (from Tim) - most editing logic moved to QgsVectorLayer - adding/deleting attributes moved to QgsVectorLayerProperties QgsIdentifyResults: - add support for attribute editing when it edit mode QgsVectorLayerProperties: add a new tab to show attribute list: * start/stop editing * add/delete attributes * assign edit type to attributes (unique values, value map, ranges) QgsAttributeDialog: add support for attribute edit types: * selection from unique value render classes (combobox) * selection from unique values of existing features (combobox or line edits with completion) * spinboxes for ranges QgsPostgresProvider: - use read-only connection for cursors and read-write connection for updates - updated native types QgsOgrProvider: - remove unused references to GEOS geometry factory - updated native types git-svn-id: http://svn.osgeo.org/qgis/trunk@9092 c8812cc2-4d05-0410-92ff-de0c093fc19c
267 lines
8.6 KiB
C++
267 lines
8.6 KiB
C++
/***************************************************************************
|
|
QgsBookmarks.cpp - Spatial Bookmarks
|
|
-------------------
|
|
begin : 2005-04-23
|
|
copyright : (C) 2005 Gary Sherman
|
|
email : sherman at mrcc dot com
|
|
***************************************************************************/
|
|
|
|
/***************************************************************************
|
|
* *
|
|
* 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$ */
|
|
#include "qgsbookmarks.h"
|
|
#include "qgisapp.h"
|
|
#include "qgsapplication.h"
|
|
#include "qgscontexthelp.h"
|
|
#include "qgsmapcanvas.h"
|
|
#include "qgslogger.h"
|
|
|
|
#include <QDir>
|
|
#include <QFileInfo>
|
|
#include <QMessageBox>
|
|
#include <QSettings>
|
|
#include <QPushButton>
|
|
|
|
//standard includes
|
|
#include <iostream>
|
|
#include <cassert>
|
|
#include <sqlite3.h>
|
|
#include <fstream>
|
|
|
|
QgsBookmarks::QgsBookmarks(QWidget *parent, Qt::WFlags fl)
|
|
: QDialog(parent, fl),
|
|
mParent(parent)
|
|
{
|
|
setupUi(this);
|
|
// user database is created at QGIS startup in QgisApp::createDB
|
|
// we just check whether there is our database [MD]
|
|
QFileInfo myFileInfo;
|
|
myFileInfo.setFile(QgsApplication::qgisSettingsDirPath());
|
|
if ( !myFileInfo.exists( ) )
|
|
{
|
|
#ifdef QGISDEBUG
|
|
std::cout << "The qgis.db does not exist" << std::endl;
|
|
#endif
|
|
}
|
|
|
|
// Note proper queens english on next line
|
|
initialise();
|
|
|
|
//
|
|
// Create the zoomto and delete buttons and add them to the
|
|
// toolbar
|
|
//
|
|
QPushButton * btnDelete = new QPushButton(tr("&Delete"));
|
|
QPushButton * btnZoomTo = new QPushButton(tr("&Zoom to"));
|
|
btnZoomTo->setDefault(true);
|
|
buttonBox->addButton(btnDelete, QDialogButtonBox::ActionRole);
|
|
buttonBox->addButton(btnZoomTo, QDialogButtonBox::ActionRole);
|
|
// connect the slot up to catch when a bookmark is deleted
|
|
connect(btnDelete, SIGNAL(clicked()), this, SLOT(on_btnDelete_clicked()));
|
|
// connect the slot up to catch when a bookmark is zoomed to
|
|
connect(btnZoomTo, SIGNAL(clicked()), this, SLOT(on_btnZoomTo_clicked()));
|
|
// connect the slot up to catch when a new bookmark is added
|
|
connect(mParent, SIGNAL(bookmarkAdded()), this, SLOT(refreshBookmarks()));
|
|
//and for help requested
|
|
connect(buttonBox, SIGNAL(helpRequested()), this, SLOT(helpRequested()));
|
|
}
|
|
|
|
// Destructor
|
|
QgsBookmarks::~QgsBookmarks()
|
|
{
|
|
saveWindowLocation();
|
|
}
|
|
|
|
void QgsBookmarks::refreshBookmarks()
|
|
{
|
|
lstBookmarks->clear();
|
|
initialise();
|
|
}
|
|
// Initialise the bookmark tree from the database
|
|
void QgsBookmarks::initialise()
|
|
{
|
|
int rc = connectDb();
|
|
if(rc == SQLITE_OK)
|
|
{
|
|
// prepare the sql statement
|
|
const char *pzTail;
|
|
sqlite3_stmt *ppStmt;
|
|
QString sql = "select * from tbl_bookmarks";
|
|
|
|
rc = sqlite3_prepare(db, sql.toUtf8(), sql.length(), &ppStmt, &pzTail);
|
|
// XXX Need to free memory from the error msg if one is set
|
|
if(rc == SQLITE_OK)
|
|
{
|
|
// get the first row of the result set
|
|
while(sqlite3_step(ppStmt) == SQLITE_ROW)
|
|
{
|
|
QTreeWidgetItem *item = new QTreeWidgetItem(lstBookmarks);
|
|
QString name = QString::fromUtf8((const char *)sqlite3_column_text(ppStmt, 1));
|
|
// sqlite3_bind_parameter_index(ppStmt, "name"));
|
|
//QgsDebugMsg("Bookmark name: " + name.toLocal8Bit().data());
|
|
item->setText(0, name);
|
|
// set the project name
|
|
item->setText(1, QString::fromUtf8((const char *)sqlite3_column_text(ppStmt, 2)));
|
|
// get the extents
|
|
QString xMin = QString::fromUtf8((const char *)sqlite3_column_text(ppStmt, 3));
|
|
QString yMin = QString::fromUtf8((const char *)sqlite3_column_text(ppStmt, 4));
|
|
QString xMax = QString::fromUtf8((const char *)sqlite3_column_text(ppStmt, 5));
|
|
QString yMax = QString::fromUtf8((const char *)sqlite3_column_text(ppStmt, 6));
|
|
// set the extents
|
|
item->setText(2, xMin + ", " + yMin + ", " + xMax + ", " + yMax);
|
|
// set the id
|
|
item->setText(3, QString::fromUtf8((const char *)sqlite3_column_text(ppStmt, 0)));
|
|
}
|
|
for (int col = 0; col < 4; col++)
|
|
{
|
|
lstBookmarks->resizeColumnToContents(col);
|
|
}
|
|
lstBookmarks->sortByColumn(0, Qt::AscendingOrder);
|
|
}
|
|
else
|
|
{
|
|
// XXX query failed -- warn the user some how
|
|
std::cout << "Failed to get bookmarks: " << sqlite3_errmsg(db) << std::endl;
|
|
}
|
|
// close the statement
|
|
sqlite3_finalize(ppStmt);
|
|
// close the database
|
|
sqlite3_close(db);
|
|
// return the srs wkt
|
|
|
|
}
|
|
}
|
|
|
|
void QgsBookmarks::restorePosition()
|
|
{
|
|
QSettings settings;
|
|
restoreGeometry(settings.value("/Windows/Bookmarks/geometry").toByteArray());
|
|
}
|
|
|
|
void QgsBookmarks::saveWindowLocation()
|
|
{
|
|
QSettings settings;
|
|
settings.setValue("/Windows/Bookmarks/geometry", saveGeometry());
|
|
}
|
|
|
|
void QgsBookmarks::on_btnDelete_clicked()
|
|
{
|
|
// get the current item
|
|
QTreeWidgetItem *item = lstBookmarks->currentItem();
|
|
if(item)
|
|
{
|
|
// make sure the user really wants to delete this bookmark
|
|
if(QMessageBox::Ok == QMessageBox::information(this,tr("Really Delete?"),
|
|
tr("Are you sure you want to delete the ") + item->text(0) + tr(" bookmark?"),
|
|
QMessageBox::Ok | QMessageBox::Cancel))
|
|
{
|
|
// remove it from the listview
|
|
item = lstBookmarks->takeTopLevelItem(lstBookmarks->indexOfTopLevelItem(item));
|
|
// delete it from the database
|
|
int rc = connectDb();
|
|
if(rc == SQLITE_OK)
|
|
{
|
|
char *errmsg;
|
|
// build the sql statement
|
|
QString sql = "delete from tbl_bookmarks where bookmark_id = " + item->text(3);
|
|
rc = sqlite3_exec(db, sql.toUtf8(), NULL, NULL, &errmsg);
|
|
if(rc != SQLITE_OK)
|
|
{
|
|
// XXX Provide popup message on failure?
|
|
QMessageBox::warning(this, tr("Error deleting bookmark"),
|
|
tr("Failed to delete the ") +
|
|
item->text(0) +
|
|
tr(" bookmark from the database. The "
|
|
"database said:\n") + QString(errmsg));
|
|
sqlite3_free(errmsg);
|
|
}
|
|
// close the database
|
|
sqlite3_close(db);
|
|
}
|
|
delete item;
|
|
}
|
|
}
|
|
}
|
|
|
|
void QgsBookmarks::on_btnZoomTo_clicked()
|
|
{
|
|
zoomToBookmark();
|
|
}
|
|
|
|
void QgsBookmarks::on_lstBookmarks_doubleClicked(QTreeWidgetItem *lvi)
|
|
{
|
|
zoomToBookmark();
|
|
}
|
|
|
|
void QgsBookmarks::zoomToBookmark()
|
|
{
|
|
// Need to fetch the extent for the selected bookmark and then redraw
|
|
// the map
|
|
// get the current item
|
|
QTreeWidgetItem *item = lstBookmarks->currentItem();
|
|
if(!item)
|
|
{
|
|
return;
|
|
}
|
|
// get the extent from the database
|
|
int rc = connectDb();
|
|
if(rc == SQLITE_OK)
|
|
{
|
|
sqlite3_stmt *ppStmt;
|
|
const char *pzTail;
|
|
// build the sql statement
|
|
QString sql = "select xmin, ymin, xmax, ymax from tbl_bookmarks where bookmark_id = " + item->text(3);
|
|
rc = sqlite3_prepare(db, sql.toUtf8(), sql.length(), &ppStmt, &pzTail);
|
|
if(rc == SQLITE_OK)
|
|
{
|
|
if(sqlite3_step(ppStmt) == SQLITE_ROW){
|
|
// get the extents from the resultset
|
|
QString xmin = QString::fromUtf8((const char *)sqlite3_column_text(ppStmt, 0));
|
|
QString ymin = QString::fromUtf8((const char *)sqlite3_column_text(ppStmt, 1));
|
|
QString xmax = QString::fromUtf8((const char *)sqlite3_column_text(ppStmt, 2));
|
|
QString ymax = QString::fromUtf8((const char *)sqlite3_column_text(ppStmt, 3));
|
|
// set the extent to the bookmark
|
|
QgisApp::instance()->setExtent(QgsRect(xmin.toDouble(),
|
|
ymin.toDouble(),
|
|
xmax.toDouble(),
|
|
ymax.toDouble()));
|
|
// redraw the map
|
|
QgisApp::instance()->getMapCanvas()->refresh();
|
|
}
|
|
}
|
|
|
|
// close the statement
|
|
sqlite3_finalize(ppStmt);
|
|
// close the database
|
|
sqlite3_close(db);
|
|
}
|
|
|
|
}
|
|
|
|
int QgsBookmarks::connectDb()
|
|
{
|
|
|
|
int rc;
|
|
rc = sqlite3_open(QgsApplication::qgisUserDbFilePath().toUtf8().data(), &db);
|
|
if(rc!=SQLITE_OK)
|
|
{
|
|
std::cout << "Can't open database: " << sqlite3_errmsg(db) << std::endl;
|
|
|
|
// XXX This will likely never happen since on open, sqlite creates the
|
|
// database if it does not exist.
|
|
assert(rc == 0);
|
|
}
|
|
return rc;
|
|
}
|
|
|
|
void QgsBookmarks::helpRequested()
|
|
{
|
|
QgsContextHelp::run(context_id);
|
|
}
|