aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatarUnit 193 <unit193@ubuntu.com>2014-12-30 00:06:58 -0500
committerLibravatarUnit 193 <unit193@ubuntu.com>2014-12-30 00:06:58 -0500
commitb9d8c3d4263a1ec43adc13e8d75f1db13bc5e57e (patch)
tree5ca832b1bb0f1a3881a2999e7e43901827d2c141
parent621314178ceda85a102d7e3403cbfa07ea94b928 (diff)
parent724c012ada23ef480c61fe99e3c9784b91aeb1ca (diff)
downloadsqlitestudio-b9d8c3d4263a1ec43adc13e8d75f1db13bc5e57e.tar.bz2
sqlitestudio-b9d8c3d4263a1ec43adc13e8d75f1db13bc5e57e.tar.xz
sqlitestudio-b9d8c3d4263a1ec43adc13e8d75f1db13bc5e57e.tar.zst
Merge tag 'upstream/3.0.1'
Upstream version 3.0.1 # gpg: Signature made Tue 30 Dec 2014 12:06:57 AM EST using RSA key ID EBE9BD91 # gpg: Good signature from "Unit 193 <unit193@gmail.com>" # gpg: aka "Unit 193 <unit193@ninthfloor.org>" # gpg: aka "Unit 193 <unit193@ubuntu.com>"
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/ChangeLog.txt6
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/TODO.txt2
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/coreSQLiteStudio.pro4
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/qt.conf2
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/sqlitestudio.cpp2
-rw-r--r--SQLiteStudio3/guiSQLiteStudio/datagrid/sqlquerymodel.cpp3
-rw-r--r--SQLiteStudio3/guiSQLiteStudio/datagrid/sqltablemodel.cpp124
-rw-r--r--SQLiteStudio3/guiSQLiteStudio/datagrid/sqltablemodel.h7
-rw-r--r--SQLiteStudio3/guiSQLiteStudio/dataview.cpp14
-rw-r--r--SQLiteStudio3/guiSQLiteStudio/dataview.h1
-rw-r--r--SQLiteStudio3/guiSQLiteStudio/dialogs/configdialog.ui48
-rw-r--r--SQLiteStudio3/guiSQLiteStudio/mainwindow.cpp42
-rw-r--r--SQLiteStudio3/guiSQLiteStudio/uiconfig.h2
13 files changed, 229 insertions, 28 deletions
diff --git a/SQLiteStudio3/coreSQLiteStudio/ChangeLog.txt b/SQLiteStudio3/coreSQLiteStudio/ChangeLog.txt
index 7042dcc..0baf02c 100644
--- a/SQLiteStudio3/coreSQLiteStudio/ChangeLog.txt
+++ b/SQLiteStudio3/coreSQLiteStudio/ChangeLog.txt
@@ -1,3 +1,9 @@
+[3.0.1]
+ * [ADDED]: When the data is being read into the Gird View, columns width gets automatically adjusted, so for small values they are shrinked and for bigger values they're enlarged, but never above the configured limit (a new option in config dialog).
+ * [ADDED]: Implemented support for immediate editing of rows just added to the WITHOUT ROWID tables (previously the manual refresh of data view was required).
+ * [BUGFIX]: Fixed support for expressions as DEFAULT value in table.
+ * [BUGFIX]: Fixed support under Windows for running portable distribution, while having different version of Qt installed in the system (added the qt.conf file).
+
[3.0.0]
* [ADDED]: Application has been rewritten from scratch in C++ and Qt (was previously written in Tcl/Tk). This means improvements in all areas, especially in application performance, good looking interface, more friendly interface and more stability.
* [ADDED]: Database list can now group databases in named groups (groups can be embedded in each other).
diff --git a/SQLiteStudio3/coreSQLiteStudio/TODO.txt b/SQLiteStudio3/coreSQLiteStudio/TODO.txt
index a86a49b..458d550 100644
--- a/SQLiteStudio3/coreSQLiteStudio/TODO.txt
+++ b/SQLiteStudio3/coreSQLiteStudio/TODO.txt
@@ -1,3 +1,5 @@
+* 3.0.1:
+
* Next versions:
- commiting DataView should be async
- syntax checkers as services - per language
diff --git a/SQLiteStudio3/coreSQLiteStudio/coreSQLiteStudio.pro b/SQLiteStudio3/coreSQLiteStudio/coreSQLiteStudio.pro
index c5c81eb..1ce7520 100644
--- a/SQLiteStudio3/coreSQLiteStudio/coreSQLiteStudio.pro
+++ b/SQLiteStudio3/coreSQLiteStudio/coreSQLiteStudio.pro
@@ -19,6 +19,7 @@ TEMPLATE = lib
win32 {
LIBS += -lpsapi $$PWD/../../../lib/libquazip.a
+ DISTFILES += qt.conf
}
linux: {
@@ -404,7 +405,8 @@ OTHER_FILES += \
licenses/lgpl.txt \
licenses/diff_match.txt \
licenses/gpl.txt \
- ChangeLog.txt
+ ChangeLog.txt \
+ qt.conf
FORMS += \
plugins/populatesequence.ui \
diff --git a/SQLiteStudio3/coreSQLiteStudio/qt.conf b/SQLiteStudio3/coreSQLiteStudio/qt.conf
new file mode 100644
index 0000000..4196808
--- /dev/null
+++ b/SQLiteStudio3/coreSQLiteStudio/qt.conf
@@ -0,0 +1,2 @@
+[Paths]
+Prefix = .
diff --git a/SQLiteStudio3/coreSQLiteStudio/sqlitestudio.cpp b/SQLiteStudio3/coreSQLiteStudio/sqlitestudio.cpp
index c253583..3595b21 100644
--- a/SQLiteStudio3/coreSQLiteStudio/sqlitestudio.cpp
+++ b/SQLiteStudio3/coreSQLiteStudio/sqlitestudio.cpp
@@ -38,7 +38,7 @@
DEFINE_SINGLETON(SQLiteStudio)
-static const int sqlitestudioVersion = 30000;
+static const int sqlitestudioVersion = 30001;
SQLiteStudio::SQLiteStudio()
{
diff --git a/SQLiteStudio3/guiSQLiteStudio/datagrid/sqlquerymodel.cpp b/SQLiteStudio3/guiSQLiteStudio/datagrid/sqlquerymodel.cpp
index 56bf78d..caeab3b 100644
--- a/SQLiteStudio3/guiSQLiteStudio/datagrid/sqlquerymodel.cpp
+++ b/SQLiteStudio3/guiSQLiteStudio/datagrid/sqlquerymodel.cpp
@@ -633,6 +633,7 @@ void SqlQueryModel::loadData(SqlQueryPtr results)
SqlResultsRowPtr row;
int rowIdx = 0;
int rowsPerPage = CFG_UI.General.NumberOfRowsPerPage.get();
+ int refreshEvery = rowsPerPage / 10;
rowNumBase = getCurrentPage() * rowsPerPage + 1;
updateColumnHeaderLabels();
@@ -646,7 +647,7 @@ void SqlQueryModel::loadData(SqlQueryPtr results)
itemList = loadRow(row);
insertRow(rowIdx, itemList);
- if ((rowIdx % 100) == 0)
+ if ((rowIdx % refreshEvery) == 0)
qApp->processEvents();
rowIdx++;
diff --git a/SQLiteStudio3/guiSQLiteStudio/datagrid/sqltablemodel.cpp b/SQLiteStudio3/guiSQLiteStudio/datagrid/sqltablemodel.cpp
index c713737..d097d55 100644
--- a/SQLiteStudio3/guiSQLiteStudio/datagrid/sqltablemodel.cpp
+++ b/SQLiteStudio3/guiSQLiteStudio/datagrid/sqltablemodel.cpp
@@ -76,7 +76,21 @@ bool SqlTableModel::commitAddedRow(const QList<SqlQueryItem*>& itemsInRow)
}
// Reloading row with actual values (because of DEFAULT, AUTOINCR)
- RowId rowId = result->getInsertRowId();
+ RowId rowId;
+ if (isWithOutRowIdTable)
+ {
+ SqlQueryItem* item = nullptr;
+ int i = 0;
+ for (const SqlQueryModelColumnPtr& modelColumn : modelColumns)
+ {
+ item = itemsInRow[i++];
+ if (modelColumn->isPk())
+ rowId[modelColumn->column] = item->getValue();
+ }
+ }
+ else
+ rowId = result->getInsertRowId();
+
updateRowAfterInsert(itemsInRow, modelColumns, rowId);
return true;
}
@@ -178,8 +192,14 @@ void SqlTableModel::resetFilter()
void SqlTableModel::updateRowAfterInsert(const QList<SqlQueryItem*>& itemsInRow, const QList<SqlQueryModelColumnPtr>& modelColumns, RowId rowId)
{
+ Dialect dialect = db->getDialect();
+
// Update cells with data just like it was entered. Only DEFAULT and PRIMARY KEY AUTOINCREMENT will have special values.
- QList<QVariant> values;
+ // If the DEFAULT is not an explicit literal, but an expression and db is SQLite3, we have to read the inserted value from DB.
+ QHash<SqlQueryModelColumnPtr,SqlQueryItem*> columnsToReadFromDb;
+ Parser parser(dialect);
+ SqliteExpr* expr = nullptr;
+ QHash<SqlQueryItem*,QVariant> values;
SqlQueryItem* item = nullptr;
int i = 0;
for (const SqlQueryModelColumnPtr& modelColumn : modelColumns)
@@ -190,26 +210,95 @@ void SqlTableModel::updateRowAfterInsert(const QList<SqlQueryItem*>& itemsInRow,
{
if (modelColumn->isDefault())
{
- values << modelColumn->getDefaultConstraint()->defaultValue;
+ if (dialect == Dialect::Sqlite3)
+ {
+ expr = parser.parseExpr(modelColumn->getDefaultConstraint()->defaultValue);
+ if (expr && expr->mode != SqliteExpr::Mode::LITERAL_VALUE)
+ {
+ if (isWithOutRowIdTable && rowId.isEmpty())
+ {
+ qWarning() << "Inserted expression as DEFAULT value for table WITHOUT ROWID and actually no ROWID."
+ << "This is currently unsupported to refresh such cell value instantly.";
+ values[item] = QVariant();
+ }
+ else
+ columnsToReadFromDb[modelColumn] = item;
+
+ continue;
+ }
+ }
+ values[item] = modelColumn->getDefaultConstraint()->defaultValue;
continue;
}
// If this is the PK AUTOINCR column we use RowId as value, because it was skipped when setting values to items
if (modelColumn->isPk() && modelColumn->isAutoIncr())
{
- values << rowId["ROWID"];
+ values[item] = rowId["ROWID"];
continue;
}
}
- values << item->getValue();
+ values[item] = item->getValue();
+ }
+
+ // Reading values for DEFAULT values being an expression
+ if (columnsToReadFromDb.size() > 0)
+ {
+ // Preparing query
+ static_qstring(limitedColTpl, "substr(%1, 1, %2)");
+ SelectColumnsQueryBuilder queryBuilder;
+ queryBuilder.setTable(wrapObjIfNeeded(table, dialect));
+ queryBuilder.setRowId(rowId);
+ QList<SqlQueryModelColumnPtr> columnKeys = columnsToReadFromDb.keys();
+ for (const SqlQueryModelColumnPtr& modelColumn : columnKeys)
+ queryBuilder.addColumn(limitedColTpl.arg(wrapObjIfNeeded(modelColumn->column, dialect), QString::number(cellDataLengthLimit)));
+
+ // Executing query
+ SqlQueryPtr defColValues = db->exec(queryBuilder.build(), queryBuilder.getQueryArgs(), Db::Flag::PRELOAD);
+
+ // Handling error
+ if (defColValues->isError())
+ {
+ qCritical() << "Could not load inserted values for DEFAULT expression in the table, so filling them with NULL. Error from database was:"
+ << defColValues->getErrorText();
+
+ for (const SqlQueryModelColumnPtr& modelColumn : columnKeys)
+ values[columnsToReadFromDb[modelColumn]] = QVariant();
+ }
+ else if (!defColValues->hasNext())
+ {
+ qCritical() << "Could not load inserted values for DEFAULT expression in the table, so filling them with NULL. There were no result rows.";
+
+ for (const SqlQueryModelColumnPtr& modelColumn : columnKeys)
+ values[columnsToReadFromDb[modelColumn]] = QVariant();
+ }
+ else
+ {
+ // Reading a row
+ SqlResultsRowPtr row = defColValues->next();
+ if (row->valueList().size() != columnKeys.size())
+ {
+ qCritical() << "Could not load inserted values for DEFAULT expression in the table, so filling them with NULL. Number of columns from results was invalid:"
+ << row->valueList().size() << ", while expected:" << columnKeys.size();
+
+ for (const SqlQueryModelColumnPtr& modelColumn : columnKeys)
+ values[columnsToReadFromDb[modelColumn]] = QVariant();
+ }
+ else
+ {
+ int colIdx = 0;
+ for (const SqlQueryModelColumnPtr& modelColumn : columnKeys)
+ values[columnsToReadFromDb[modelColumn]] = row->value(colIdx++);
+ }
+ }
}
// Update cell data with results
int colIdx = 0;
for (SqlQueryItem* itemToUpdate : itemsInRow)
{
- updateItem(itemToUpdate, values[colIdx], colIdx, rowId);
+ updateItem(itemToUpdate, values[itemToUpdate], colIdx, rowId);
if (isWithOutRowIdTable && rowId.isEmpty())
itemToUpdate->setJustInsertedWithOutRowId(true);
@@ -328,5 +417,26 @@ QString SqlTableModel::CommitDeleteQueryBuilder::build()
dbAndTable += table;
QString conditions = RowIdConditionBuilder::build();
- return "DELETE FROM "+dbAndTable+" WHERE "+conditions+";";
+
+ static_qstring(sql, "DELETE FROM %1 WHERE %2;");
+ return sql.arg(dbAndTable, conditions);
+}
+
+
+QString SqlTableModel::SelectColumnsQueryBuilder::build()
+{
+ QString dbAndTable;
+ if (!database.isNull())
+ dbAndTable += database+".";
+
+ dbAndTable += table;
+ QString conditions = RowIdConditionBuilder::build();
+
+ static_qstring(sql, "SELECT %1 FROM %2 WHERE %3 LIMIT 1;");
+ return sql.arg(columns.join(", "), dbAndTable, conditions);
+}
+
+void SqlTableModel::SelectColumnsQueryBuilder::addColumn(const QString& col)
+{
+ columns << col;
}
diff --git a/SQLiteStudio3/guiSQLiteStudio/datagrid/sqltablemodel.h b/SQLiteStudio3/guiSQLiteStudio/datagrid/sqltablemodel.h
index 6adb5b6..8b76acc 100644
--- a/SQLiteStudio3/guiSQLiteStudio/datagrid/sqltablemodel.h
+++ b/SQLiteStudio3/guiSQLiteStudio/datagrid/sqltablemodel.h
@@ -31,6 +31,13 @@ class GUI_API_EXPORT SqlTableModel : public SqlQueryModel
QString build();
};
+ class SelectColumnsQueryBuilder : public CommitUpdateQueryBuilder
+ {
+ public:
+ QString build();
+ void addColumn(const QString& col);
+ };
+
void updateColumnsAndValuesWithDefaultValues(const QList<SqlQueryModelColumnPtr>& modelColumns, QStringList& colNameList,
QStringList& sqlValues, QList<QVariant>& args);
diff --git a/SQLiteStudio3/guiSQLiteStudio/dataview.cpp b/SQLiteStudio3/guiSQLiteStudio/dataview.cpp
index c7f615a..e99b9b8 100644
--- a/SQLiteStudio3/guiSQLiteStudio/dataview.cpp
+++ b/SQLiteStudio3/guiSQLiteStudio/dataview.cpp
@@ -241,6 +241,17 @@ void DataView::setupDefShortcuts()
BIND_SHORTCUTS(DataView, Action);
}
+void DataView::resizeColumnsInitiallyToContents()
+{
+ int cols = gridView->model()->columnCount();
+ gridView->resizeColumnsToContents();
+ for (int i = 0; i < cols ; i++)
+ {
+ if (gridView->columnWidth(i) > CFG_UI.General.MaxInitialColumnWith.get())
+ gridView->setColumnWidth(i, CFG_UI.General.MaxInitialColumnWith.get());
+ }
+}
+
void DataView::createStaticActions()
{
// Filtering actions
@@ -544,7 +555,10 @@ bool DataView::isUncommited() const
void DataView::dataLoadingEnded(bool successful)
{
if (successful)
+ {
updatePageEdit();
+ resizeColumnsInitiallyToContents();
+ }
setNavigationState(true);
}
diff --git a/SQLiteStudio3/guiSQLiteStudio/dataview.h b/SQLiteStudio3/guiSQLiteStudio/dataview.h
index 19e56c0..5207fdb 100644
--- a/SQLiteStudio3/guiSQLiteStudio/dataview.h
+++ b/SQLiteStudio3/guiSQLiteStudio/dataview.h
@@ -83,6 +83,7 @@ class GUI_API_EXPORT DataView : public QTabWidget, public ExtActionContainer
protected:
void createActions();
void setupDefShortcuts();
+ void resizeColumnsInitiallyToContents();
private:
enum class TabsPosition
diff --git a/SQLiteStudio3/guiSQLiteStudio/dialogs/configdialog.ui b/SQLiteStudio3/guiSQLiteStudio/dialogs/configdialog.ui
index 82cc286..040600e 100644
--- a/SQLiteStudio3/guiSQLiteStudio/dialogs/configdialog.ui
+++ b/SQLiteStudio3/guiSQLiteStudio/dialogs/configdialog.ui
@@ -263,6 +263,35 @@
</property>
</widget>
</item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="initColWidthLimitLabel">
+ <property name="toolTip">
+ <string>&lt;p&gt;When the data is read into grid view columns width is automatically adjusted. This value limits the initial width for the adjustment, but user can still resize the column manually over this limit.&lt;/p&gt;</string>
+ </property>
+ <property name="text">
+ <string>Limit initial data column width to (in pixels):</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QSpinBox" name="initColWidthLimitSpin">
+ <property name="toolTip">
+ <string>&lt;p&gt;When the data is read into grid view columns width is automatically adjusted. This value limits the initial width for the adjustment, but user can still resize the column manually over this limit.&lt;/p&gt;</string>
+ </property>
+ <property name="minimum">
+ <number>10</number>
+ </property>
+ <property name="maximum">
+ <number>99999</number>
+ </property>
+ <property name="value">
+ <number>600</number>
+ </property>
+ <property name="cfg" stdset="0">
+ <string>General.MaxInitialColumnWith</string>
+ </property>
+ </widget>
+ </item>
</layout>
</widget>
</item>
@@ -499,6 +528,25 @@
</widget>
</item>
<item>
+ <widget class="QGroupBox" name="sessionGroup">
+ <property name="title">
+ <string>Session</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_11">
+ <item row="0" column="0">
+ <widget class="QCheckBox" name="sessionCheck">
+ <property name="text">
+ <string>Restore last session (active MDI windows) after startup</string>
+ </property>
+ <property name="cfg" stdset="0">
+ <string>General.RestoreSession</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
diff --git a/SQLiteStudio3/guiSQLiteStudio/mainwindow.cpp b/SQLiteStudio3/guiSQLiteStudio/mainwindow.cpp
index df8799b..7dbde8c 100644
--- a/SQLiteStudio3/guiSQLiteStudio/mainwindow.cpp
+++ b/SQLiteStudio3/guiSQLiteStudio/mainwindow.cpp
@@ -420,17 +420,20 @@ void MainWindow::saveSession(MdiWindow* currWindow)
sessionValue["state"] = saveState();
sessionValue["geometry"] = saveGeometry();
- QList<QVariant> windowSessions;
- foreach (MdiWindow* window, ui->mdiArea->getWindows())
- if (window->restoreSessionNextTime())
- windowSessions << window->saveSession();
-
- sessionValue["windowSessions"] = windowSessions;
-
- if (currWindow && currWindow->restoreSessionNextTime())
+ if (CFG_UI.General.RestoreSession.get())
{
- QString title = currWindow->windowTitle();
- sessionValue["activeWindowTitle"] = title;
+ QList<QVariant> windowSessions;
+ foreach (MdiWindow* window, ui->mdiArea->getWindows())
+ if (window->restoreSessionNextTime())
+ windowSessions << window->saveSession();
+
+ sessionValue["windowSessions"] = windowSessions;
+
+ if (currWindow && currWindow->restoreSessionNextTime())
+ {
+ QString title = currWindow->windowTitle();
+ sessionValue["activeWindowTitle"] = title;
+ }
}
sessionValue["dbTree"] = dbTree->saveSession();
@@ -457,15 +460,18 @@ void MainWindow::restoreSession()
if (sessionValue.contains("dbTree"))
dbTree->restoreSession(sessionValue["dbTree"]);
- if (sessionValue.contains("windowSessions"))
- restoreWindowSessions(sessionValue["windowSessions"].toList());
-
- if (sessionValue.contains("activeWindowTitle"))
+ if (CFG_UI.General.RestoreSession.get())
{
- QString title = sessionValue["activeWindowTitle"].toString();
- MdiWindow* window = ui->mdiArea->getWindowByTitle(title);
- if (window)
- ui->mdiArea->setActiveSubWindow(window);
+ if (sessionValue.contains("windowSessions"))
+ restoreWindowSessions(sessionValue["windowSessions"].toList());
+
+ if (sessionValue.contains("activeWindowTitle"))
+ {
+ QString title = sessionValue["activeWindowTitle"].toString();
+ MdiWindow* window = ui->mdiArea->getWindowByTitle(title);
+ if (window)
+ ui->mdiArea->setActiveSubWindow(window);
+ }
}
if (statusField->hasMessages())
diff --git a/SQLiteStudio3/guiSQLiteStudio/uiconfig.h b/SQLiteStudio3/guiSQLiteStudio/uiconfig.h
index 7b645e1..608ce47 100644
--- a/SQLiteStudio3/guiSQLiteStudio/uiconfig.h
+++ b/SQLiteStudio3/guiSQLiteStudio/uiconfig.h
@@ -73,11 +73,13 @@ CFG_CATEGORIES(Ui,
CFG_ENTRY(int, NumberOfRowsPerPage, 1000)
CFG_ENTRY(QString, Style, &Cfg::getStyleDefaultValue)
CFG_ENTRY(Cfg::Session, Session, Cfg::Session())
+ CFG_ENTRY(bool, RestoreSession, true)
CFG_ENTRY(bool, DontShowDdlPreview, false)
CFG_ENTRY(bool, OpenTablesOnData, false)
CFG_ENTRY(bool, OpenViewsOnData, false)
CFG_ENTRY(Cfg::DataEditorsOrder, DataEditorsOrder, Cfg::DataEditorsOrder())
CFG_ENTRY(QString, FileDialogLastPath, QString())
+ CFG_ENTRY(int, MaxInitialColumnWith, 600)
)
)