diff options
| author | 2016-06-13 18:42:42 -0400 | |
|---|---|---|
| committer | 2016-06-13 18:42:42 -0400 | |
| commit | 5d9314f134ddd3dc4c853e398ac90ba247fb2e4f (patch) | |
| tree | 5c457fc188036988d7abd29a3eb09931e406510f /SQLiteStudio3/guiSQLiteStudio/dbtree | |
| parent | 8e640722c62692818ab840d50b3758f89a41a54e (diff) | |
Imported Upstream version 3.1.0upstream/3.1.0
Diffstat (limited to 'SQLiteStudio3/guiSQLiteStudio/dbtree')
| -rw-r--r-- | SQLiteStudio3/guiSQLiteStudio/dbtree/dbtree.cpp | 232 | ||||
| -rw-r--r-- | SQLiteStudio3/guiSQLiteStudio/dbtree/dbtree.h | 23 | ||||
| -rw-r--r-- | SQLiteStudio3/guiSQLiteStudio/dbtree/dbtreemodel.cpp | 36 | ||||
| -rw-r--r-- | SQLiteStudio3/guiSQLiteStudio/dbtree/dbtreemodel.h | 1 |
4 files changed, 240 insertions, 52 deletions
diff --git a/SQLiteStudio3/guiSQLiteStudio/dbtree/dbtree.cpp b/SQLiteStudio3/guiSQLiteStudio/dbtree/dbtree.cpp index 62d7368..fbe0a38 100644 --- a/SQLiteStudio3/guiSQLiteStudio/dbtree/dbtree.cpp +++ b/SQLiteStudio3/guiSQLiteStudio/dbtree/dbtree.cpp @@ -24,6 +24,9 @@ #include "services/importmanager.h" #include "windows/editorwindow.h" #include "uiconfig.h" +#include "themetuner.h" +#include "dialogs/dbconverterdialog.h" +#include "querygenerator.h" #include <QApplication> #include <QClipboard> #include <QAction> @@ -34,8 +37,7 @@ #include <QDebug> #include <QKeyEvent> #include <QMimeData> -#include <themetuner.h> -#include <dialogs/dbconverterdialog.h> +#include <QDebug> CFG_KEYS_DEFINE(DbTree) QHash<DbTreeItem::Type,QList<DbTreeItem::Type>> DbTree::allowedTypesInside; @@ -140,6 +142,10 @@ void DbTree::createActions() createAction(REFRESH_SCHEMAS, ICONS.DATABASE_RELOAD, tr("Refresh all database schemas"), this, SLOT(refreshSchemas()), this); createAction(REFRESH_SCHEMA, ICONS.DATABASE_RELOAD, tr("Refresh selected database schema"), this, SLOT(refreshSchema()), this); createAction(ERASE_TABLE_DATA, ICONS.ERASE_TABLE_DATA, tr("Erase table data"), this, SLOT(eraseTableData()), this); + createAction(GENERATE_SELECT, "SELECT", this, SLOT(generateSelectForTable()), this); + createAction(GENERATE_INSERT, "INSERT", this, SLOT(generateInsertForTable()), this); + createAction(GENERATE_UPDATE, "UPDATE", this, SLOT(generateUpdateForTable()), this); + createAction(GENERATE_DELETE, "DELETE", this, SLOT(generateDeleteForTable()), this); } void DbTree::updateActionStates(const QStandardItem *item) @@ -194,6 +200,7 @@ void DbTree::updateActionStates(const QStandardItem *item) case DbTreeItem::Type::TABLE: enabled << EDIT_TABLE << DEL_TABLE << EXPORT_TABLE << IMPORT_TABLE << POPULATE_TABLE << ADD_COLUMN << CREATE_SIMILAR_TABLE; enabled << RESET_AUTOINCREMENT << ADD_INDEX << ADD_TRIGGER << ERASE_TABLE_DATA; + enabled << GENERATE_SELECT << GENERATE_INSERT << GENERATE_UPDATE << GENERATE_DELETE; break; case DbTreeItem::Type::VIRTUAL_TABLE: // TODO change below when virtual tables can be edited @@ -329,6 +336,12 @@ void DbTree::setupActionsForMenu(DbTreeItem* currItem, QMenu* contextMenu) groupEntry += RENAME_GROUP; groupEntry += DELETE_GROUP; + ActionEntry genQueryEntry(ICONS.GENERATE_QUERY, tr("Generate query for table")); + genQueryEntry += GENERATE_SELECT; + genQueryEntry += GENERATE_INSERT; + genQueryEntry += GENERATE_UPDATE; + genQueryEntry += GENERATE_DELETE; + if (currItem) { DbTreeItem* parentItem = currItem->parentDbTreeItem(); @@ -392,6 +405,7 @@ void DbTree::setupActionsForMenu(DbTreeItem* currItem, QMenu* contextMenu) actions += ActionEntry(ADD_INDEX); actions += ActionEntry(ADD_TRIGGER); actions += ActionEntry(_separator); + actions += genQueryEntry; actions += ActionEntry(IMPORT_TABLE); actions += ActionEntry(EXPORT_TABLE); actions += ActionEntry(POPULATE_TABLE); @@ -635,11 +649,13 @@ bool DbTree::areDbTreeItemsValidForItem(QList<DbTreeItem*> srcItems, const DbTre for (DbTreeItem* srcItem : srcItems) { - if (srcItem) - srcTypes << srcItem->getType(); - else + if (!srcItem) + { srcTypes << DbTreeItem::Type::ITEM_PROTOTYPE; + continue; + } + srcTypes << srcItem->getType(); if (srcItem->getDb()) srcDbs << srcItem->getDb(); } @@ -653,6 +669,18 @@ bool DbTree::areDbTreeItemsValidForItem(QList<DbTreeItem*> srcItems, const DbTre return false; } + // Support for d&d reordering of db objects + static const QHash<DbTreeItem::Type, DbTreeItem::Type> reorderingTypeToParent = { + {DbTreeItem::Type::TABLE, DbTreeItem::Type::TABLES}, + {DbTreeItem::Type::TRIGGER, DbTreeItem::Type::TRIGGERS}, + {DbTreeItem::Type::VIEW, DbTreeItem::Type::VIEWS}, + {DbTreeItem::Type::INDEX, DbTreeItem::Type::INDEXES} + }; + + if (srcTypes.toSet().size() == 1 && srcDbs.size() == 1 && dstItem && *(srcDbs.begin()) == dstItem->getDb() && reorderingTypeToParent[srcTypes.first()] == dstType) + return true; + + // No other d&d within same db if (dstItem && dstItem->getDb() && srcDbs.contains(dstItem->getDb())) return false; @@ -706,6 +734,16 @@ Db* DbTree::getSelectedDb() return item->getDb(); } +QSet<Db*> DbTree::getSelectedDatabases() +{ + QList<DbTreeItem*> items = ui->treeView->selectionItems(); + QSet<Db*> dbList; + for (DbTreeItem* item : items) + dbList << item->getDb(); + + return dbList; +} + Db* DbTree::getSelectedOpenDb() { Db* db = getSelectedDb(); @@ -872,6 +910,72 @@ void DbTree::deleteItem(DbTreeItem* item) } } +void DbTree::deleteSelected(DbTreeItem::Type itemType) +{ + deleteSelected([itemType](DbTreeItem* item) + { + return item->getType() == itemType; + }); +} + +QHash<Db*, QList<DbTreeItem*>> DbTree::groupByDb(const QList<DbTreeItem*> items) +{ + QHash<Db*, QList<DbTreeItem*>> grouped; + for (DbTreeItem* item : items) + grouped[item->getDb()] << item; + + return grouped; +} + +QStringList DbTree::itemsToNames(const QList<DbTreeItem*>& items) +{ + QStringList names; + for (DbTreeItem* item : items) + names << item->text(); + + return names; +} + +QString DbTree::getSelectedTableName() const +{ + DbTreeItem* item = ui->treeView->currentItem(); + QString table = item->getTable(); + if (table.isNull()) + return QString(); + + return table; +} + +QString DbTree::getSelectedIndexName() const +{ + DbTreeItem* item = ui->treeView->currentItem(); + QString idx = item->getIndex(); + if (idx.isNull()) + return QString(); + + return idx; +} + +QString DbTree::getSelectedTriggerName() const +{ + DbTreeItem* item = ui->treeView->currentItem(); + QString trig = item->getTrigger(); + if (trig.isNull()) + return QString(); + + return trig; +} + +QString DbTree::getSelectedViewName() const +{ + DbTreeItem* item = ui->treeView->currentItem(); + QString view= item->getView(); + if (view.isNull()) + return QString(); + + return view; +} + void DbTree::refreshSchema(Db* db) { @@ -1012,15 +1116,29 @@ void DbTree::editDb() void DbTree::removeDb() { - Db* db = getSelectedDb(); - if (!db) + QList<Db*> dbList = getSelectedDatabases().toList(); + if (dbList.isEmpty()) return; - QMessageBox::StandardButton result = QMessageBox::question(this, tr("Delete database"), tr("Are you sure you want to delete database '%1'?").arg(db->getName().left(ITEM_TEXT_LIMIT))); + QString msg; + if (dbList.size() == 1) + { + msg = tr("Are you sure you want to remove database '%1' from the list?").arg(dbList.first()->getName().left(ITEM_TEXT_LIMIT)); + } + else + { + QStringList dbNames; + for (Db* db : dbList) + dbNames << db->getName().left(ITEM_TEXT_LIMIT); + + msg = tr("Are you sure you want to remove following databases from the list:\n%1").arg(dbNames.join(",\n")); + } + QMessageBox::StandardButton result = QMessageBox::question(this, tr("Remove database"), msg); if (result != QMessageBox::Yes) return; - DBLIST->removeDb(db); + for (Db* db : dbList) + DBLIST->removeDb(db); } void DbTree::connectToDb() @@ -1097,8 +1215,7 @@ void DbTree::editTable() if (!db || !db->isValid()) return; - DbTreeItem* item = ui->treeView->currentItem(); - QString table = item->getTable(); + QString table = getSelectedTableName(); if (table.isNull()) { qWarning() << "Tried to edit table, while table wasn't selected in DbTree."; @@ -1110,20 +1227,7 @@ void DbTree::editTable() void DbTree::delTable() { - Db* db = getSelectedOpenDb(); - if (!db || !db->isValid()) - return; - - DbTreeItem* item = ui->treeView->currentItem(); - QString table = item->getTable(); - if (table.isNull()) - { - qWarning() << "Tried to drop table, while table wasn't selected in DbTree."; - return; - } - - DbObjectDialogs dialogs(db); - dialogs.dropObject(table); // TODO add database prefix when supported + deleteSelected(DbTreeItem::Type::TABLE); } void DbTree::addIndex() @@ -1145,8 +1249,7 @@ void DbTree::editIndex() if (!db || !db->isValid()) return; - DbTreeItem* item = ui->treeView->currentItem(); - QString index = item->getIndex(); + QString index = getSelectedIndexName(); DbObjectDialogs dialogs(db); dialogs.editIndex(index); @@ -1154,7 +1257,7 @@ void DbTree::editIndex() void DbTree::delIndex() { - delSelectedObject(); + deleteSelected(DbTreeItem::Type::INDEX); } void DbTree::addTrigger() @@ -1177,8 +1280,7 @@ void DbTree::editTrigger() if (!db || !db->isValid()) return; - DbTreeItem* item = ui->treeView->currentItem(); - QString trigger = item->getTrigger(); + QString trigger = getSelectedTriggerName(); DbObjectDialogs dialogs(db); dialogs.editTrigger(trigger); @@ -1186,7 +1288,7 @@ void DbTree::editTrigger() void DbTree::delTrigger() { - delSelectedObject(); + deleteSelected(DbTreeItem::Type::TRIGGER); } void DbTree::addView() @@ -1205,8 +1307,7 @@ void DbTree::editView() if (!db || !db->isValid()) return; - DbTreeItem* item = ui->treeView->currentItem(); - QString view = item->getView(); + QString view = getSelectedViewName(); if (view.isNull()) { qWarning() << "Tried to edit view, while view wasn't selected in DbTree."; @@ -1218,7 +1319,7 @@ void DbTree::editView() void DbTree::delView() { - delSelectedObject(); + deleteSelected(DbTreeItem::Type::VIEW); } void DbTree::exportTable() @@ -1334,11 +1435,12 @@ void DbTree::vacuumDb() if (!db || !db->isValid()) return; - SqlQueryPtr res = db->exec("VACUUM;"); - if (res->isError()) - notifyError(tr("Error while executing VACUUM on the database %1: %2").arg(db->getName(), res->getErrorText())); - else - notifyInfo(tr("VACUUM execution finished successfully.")); + EditorWindow* win = MAINWINDOW->openSqlEditor(db, "VACUUM;"); + if (!win) + return; + + win->getMdiWindow()->rename(tr("Vacuum (%1)").arg(db->getName())); + win->execute(); } void DbTree::integrityCheck() @@ -1347,16 +1449,11 @@ void DbTree::integrityCheck() if (!db || !db->isValid()) return; - EditorWindow* win = MAINWINDOW->openSqlEditor(); - if (!win->setCurrentDb(db)) - { - qCritical() << "Created EditorWindow had not got requested database:" << db->getName(); - win->close(); + EditorWindow* win = MAINWINDOW->openSqlEditor(db, "PRAGMA integrity_check;"); + if (!win) return; - } win->getMdiWindow()->rename(tr("Integrity check (%1)").arg(db->getName())); - win->setContents("PRAGMA integrity_check;"); win->execute(); } @@ -1493,12 +1590,19 @@ void DbTree::currentChanged(const QModelIndex ¤t, const QModelIndex &previ updateActionStates(treeModel->itemFromIndex(current)); } -void DbTree::deleteSelected() +void DbTree::deleteSelected(ItemFilterFunc filterFunc) { QModelIndexList idxList = ui->treeView->getSelectedIndexes(); QList<DbTreeItem*> items; - foreach (const QModelIndex& idx, idxList) - items << dynamic_cast<DbTreeItem*>(treeModel->itemFromIndex(idx)); + DbTreeItem* item; + for (const QModelIndex& idx : idxList) + { + item = dynamic_cast<DbTreeItem*>(treeModel->itemFromIndex(idx)); + if (filterFunc && !filterFunc(item)) + continue; + + items << item; + } deleteItems(items); } @@ -1615,6 +1719,36 @@ void DbTree::refreshFont() ui->treeView->doItemsLayout(); } +void DbTree::generateSelectForTable() +{ + Db* db = getSelectedDb(); + QString table = getSelectedTableName(); + + QueryGenerator generator; + QString sql = generator.generateSelectFromTable(db, table); + MAINWINDOW->openSqlEditor(db, sql); +} + +void DbTree::generateInsertForTable() +{ + Db* db = getSelectedDb(); + QString table = getSelectedTableName(); + + QueryGenerator generator; + QString sql = generator.generateInsertToTable(db, table); + MAINWINDOW->openSqlEditor(db, sql); +} + +void DbTree::generateUpdateForTable() +{ + +} + +void DbTree::generateDeleteForTable() +{ + +} + void DbTree::setupDefShortcuts() { setShortcutContext({ diff --git a/SQLiteStudio3/guiSQLiteStudio/dbtree/dbtree.h b/SQLiteStudio3/guiSQLiteStudio/dbtree/dbtree.h index 2f5583e..ea415a4 100644 --- a/SQLiteStudio3/guiSQLiteStudio/dbtree/dbtree.h +++ b/SQLiteStudio3/guiSQLiteStudio/dbtree/dbtree.h @@ -7,6 +7,7 @@ #include "dbtree/dbtreeitem.h" #include "guiSQLiteStudio_global.h" #include <QDockWidget> +#include <QSet> class WidgetCover; class QAction; @@ -85,6 +86,10 @@ class GUI_API_EXPORT DbTree : public QDockWidget, public ExtActionContainer CREATE_SIMILAR_TABLE, RESET_AUTOINCREMENT, ERASE_TABLE_DATA, + GENERATE_SELECT, + GENERATE_UPDATE, + GENERATE_INSERT, + GENERATE_DELETE, _separator // Never use it directly, it's just for menu setup }; @@ -111,6 +116,7 @@ class GUI_API_EXPORT DbTree : public QDockWidget, public ExtActionContainer QToolBar* getToolBar(int toolbar) const; Db* getSelectedDb(); Db* getSelectedOpenDb(); + QSet<Db*> getSelectedDatabases(); static bool isItemDraggable(const DbTreeItem* item); @@ -120,6 +126,8 @@ class GUI_API_EXPORT DbTree : public QDockWidget, public ExtActionContainer void closeEvent(QCloseEvent* e); private: + typedef std::function<bool(DbTreeItem*)> ItemFilterFunc; + void setActionEnabled(int action, bool enabled); TableWindow* openTable(DbTreeItem* item); TableWindow* openTable(Db* db, const QString& database, const QString& table); @@ -133,9 +141,16 @@ class GUI_API_EXPORT DbTree : public QDockWidget, public ExtActionContainer void filterUndeletableItems(QList<DbTreeItem*>& items); void filterItemsWithParentInList(QList<DbTreeItem*>& items); void deleteItem(DbTreeItem* item); + void deleteSelected(DbTreeItem::Type itemType); + QHash<Db*, QList<DbTreeItem*>> groupByDb(const QList<DbTreeItem*> items); + QStringList itemsToNames(const QList<DbTreeItem*>& items); + QString getSelectedTableName() const; + QString getSelectedIndexName() const; + QString getSelectedTriggerName() const; + QString getSelectedViewName() const; + static bool areDbTreeItemsValidForItem(QList<DbTreeItem*> srcItems, const DbTreeItem* dstItem); static bool areUrlsValidForItem(const QList<QUrl>& srcUrls, const DbTreeItem* dstItem); - static void initDndTypes(); Ui::DbTree *ui = nullptr; @@ -194,13 +209,17 @@ class GUI_API_EXPORT DbTree : public QDockWidget, public ExtActionContainer void editColumn(DbTreeItem* item); void delColumn(DbTreeItem* item); void currentChanged(const QModelIndex & current, const QModelIndex & previous); - void deleteSelected(); + void deleteSelected(ItemFilterFunc filterFunc = nullptr); void deleteItems(const QList<DbTreeItem*>& itemsToDelete); void refreshSchema(); void dbConnected(Db* db); void dbDisconnected(Db* db); void updateDbIcon(Db* db); void refreshFont(); + void generateSelectForTable(); + void generateInsertForTable(); + void generateUpdateForTable(); + void generateDeleteForTable(); }; int qHash(DbTree::Action action); diff --git a/SQLiteStudio3/guiSQLiteStudio/dbtree/dbtreemodel.cpp b/SQLiteStudio3/guiSQLiteStudio/dbtree/dbtreemodel.cpp index c0f527f..c11221d 100644 --- a/SQLiteStudio3/guiSQLiteStudio/dbtree/dbtreemodel.cpp +++ b/SQLiteStudio3/guiSQLiteStudio/dbtree/dbtreemodel.cpp @@ -13,6 +13,7 @@ #include "dialogs/errorsconfirmdialog.h" #include "dialogs/versionconvertsummarydialog.h" #include "db/invaliddb.h" +#include "services/notifymanager.h" #include <QMimeData> #include <QDebug> #include <QFile> @@ -1040,7 +1041,10 @@ bool DbTreeModel::dropDbTreeItem(const QList<DbTreeItem*>& srcItems, DbTreeItem* return false; if (srcItem->getDb() == dstItem->getDb()) + { + invokeStdDropAction = true; return true; + } return dropDbObjectItem(srcItems, dstItem, defaultAction); } @@ -1135,6 +1139,8 @@ QCheckBox* DbTreeModel::createCopyOrMoveMenuCheckBox(QMenu* menu, const QString& bool DbTreeModel::dropUrls(const QList<QUrl>& urls) { + QString filePath; + bool autoTest = false; for (const QUrl& url : urls) { if (!url.isLocalFile()) @@ -1143,13 +1149,41 @@ bool DbTreeModel::dropUrls(const QList<QUrl>& urls) continue; } + autoTest = false; + filePath = url.toLocalFile(); + if (CFG_UI.General.BypassDbDialogWhenDropped.get()) + { + if (quickAddDroppedDb(filePath)) + { + continue; + } + else + { + notifyWarn(tr("Could not add dropped database file '%1' automatically. Manual setup is necessary.").arg(filePath)); + autoTest = true; + } + } + DbDialog dialog(DbDialog::ADD, MAINWINDOW); - dialog.setPath(url.toLocalFile()); + dialog.setPath(filePath); + dialog.setDoAutoTest(autoTest); dialog.exec(); } return false; } +bool DbTreeModel::quickAddDroppedDb(const QString& filePath) +{ + DbPlugin* plugin = DBLIST->getPluginForDbFile(filePath); + if (!plugin) + return false; + + QString name = DBLIST->generateUniqueDbName(plugin, filePath); + QHash<QString,QVariant> opts; + opts[DB_PLUGIN] = plugin->getName(); + return DBLIST->addDb(name, filePath, opts, !CFG_UI.General.NewDbNotPermanentByDefault.get()); +} + void DbTreeModel::moveOrCopyDbObjects(const QList<DbTreeItem*>& srcItems, DbTreeItem* dstItem, bool move, bool includeData, bool includeIndexes, bool includeTriggers) { if (srcItems.size() == 0) diff --git a/SQLiteStudio3/guiSQLiteStudio/dbtree/dbtreemodel.h b/SQLiteStudio3/guiSQLiteStudio/dbtree/dbtreemodel.h index ee97e87..122421a 100644 --- a/SQLiteStudio3/guiSQLiteStudio/dbtree/dbtreemodel.h +++ b/SQLiteStudio3/guiSQLiteStudio/dbtree/dbtreemodel.h @@ -85,6 +85,7 @@ class GUI_API_EXPORT DbTreeModel : public QStandardItemModel bool dropDbObjectItem(const QList<DbTreeItem*>& srcItems, DbTreeItem* dstItem, Qt::DropAction defaultAction); QCheckBox* createCopyOrMoveMenuCheckBox(QMenu* menu, const QString& label); bool dropUrls(const QList<QUrl>& urls); + bool quickAddDroppedDb(const QString& filePath); void moveOrCopyDbObjects(const QList<DbTreeItem*>& srcItems, DbTreeItem* dstItem, bool move, bool includeData, bool includeIndexes, bool includeTriggers); static bool confirmReferencedTables(const QStringList& tables); |
