-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
/
Application.cpp
234 lines (211 loc) · 9.71 KB
/
Application.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
#include <QFile>
#include <QFileOpenEvent>
#include <QTranslator>
#include <QTextCodec>
#include <QLibraryInfo>
#include <QLocale>
#include <QDebug>
#include <QAction>
#include "Application.h"
#include "MainWindow.h"
#include "Settings.h"
#include "version.h"
Application::Application(int& argc, char** argv) :
QApplication(argc, argv)
{
// Set organisation and application names
setOrganizationName("sqlitebrowser");
setApplicationName("DB Browser for SQLite");
// Set character encoding to UTF8
QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
// Load translations
bool ok;
QString name = Settings::getValue("General", "language").toString();
// First of all try to load the application translation file.
m_translatorApp = new QTranslator(this);
ok = m_translatorApp->load("sqlb_" + name,
QCoreApplication::applicationDirPath() + "/translations");
// If failed then try to load .qm file from resources
if (ok == false) {
ok = m_translatorApp->load("sqlb_" + name, ":/translations");
}
if (ok == true) {
Settings::setValue("General", "language", name);
installTranslator(m_translatorApp);
// The application translation file has been found and loaded.
// And now try to load a Qt translation file.
// Search path:
// 1) standard Qt translations directory;
// 2) the application translations directory.
m_translatorQt = new QTranslator(this);
ok = m_translatorQt->load("qt_" + name,
QLibraryInfo::location(QLibraryInfo::TranslationsPath));
if (ok == false)
ok = m_translatorQt->load("qt_" + name, "translations");
if (ok == true)
installTranslator(m_translatorQt);
} else {
// Set the correct locale so that the program won't erroneously detect
// a language change when the user toggles settings for the first time.
// (it also prevents the program from always looking for a translation on launch)
Settings::setValue("General", "language", "en_US");
// Don't install a translator for Qt texts if no translator for DB4S texts could be loaded
m_translatorQt = nullptr;
}
// On Windows, add the plugins subdirectory to the list of library directories. We need this
// for Qt to search for more image format plugins.
#ifdef Q_WS_WIN
QApplication::addLibraryPath(QApplication::applicationDirPath() + "/plugins");
#endif
// Work around a bug in QNetworkAccessManager which sporadically causes high pings for Wifi connections
// See https://bugreports.qt.io/browse/QTBUG-40332
qputenv("QT_BEARER_POLL_TIMEOUT", QByteArray::number(INT_MAX));
// Parse command line
QString fileToOpen;
QString tableToBrowse;
QStringList sqlToExecute;
bool readOnly = false;
m_dontShowMainWindow = false;
for(int i=1;i<arguments().size();i++)
{
// Check next command line argument
if(arguments().at(i) == "-h" || arguments().at(i) == "--help")
{
// Help
qWarning() << qPrintable(tr("Usage: %1 [options] [db]\n").arg(argv[0]));
qWarning() << qPrintable(tr("Possible command line arguments:"));
qWarning() << qPrintable(tr(" -h, --help\t\tShow command line options"));
qWarning() << qPrintable(tr(" -q, --quit\t\tExit application after running scripts"));
qWarning() << qPrintable(tr(" -s, --sql [file]\tExecute this SQL file after opening the DB"));
qWarning() << qPrintable(tr(" -t, --table [table]\tBrowse this table after opening the DB"));
qWarning() << qPrintable(tr(" -R, --read-only\tOpen database in read-only mode"));
qWarning() << qPrintable(tr(" -o, --option [group/setting=value]\tRun application with this setting temporarily set to value"));
qWarning() << qPrintable(tr(" -O, --save-option [group/setting=value]\tRun application saving this value for this setting"));
qWarning() << qPrintable(tr(" -v, --version\t\tDisplay the current version"));
qWarning() << qPrintable(tr(" [file]\t\tOpen this SQLite database"));
m_dontShowMainWindow = true;
} else if(arguments().at(i) == "-v" || arguments().at(i) == "--version") {
qWarning() << qPrintable(tr("This is DB Browser for SQLite version %1.").arg(versionString()));
m_dontShowMainWindow = true;
} else if(arguments().at(i) == "-s" || arguments().at(i) == "--sql") {
// Run SQL file: If file exists add it to list of scripts to execute
if(++i >= arguments().size())
qWarning() << qPrintable(tr("The -s/--sql option requires an argument"));
else if(!QFile::exists(arguments().at(i)))
qWarning() << qPrintable(tr("The file %1 does not exist").arg(arguments().at(i)));
else
sqlToExecute.append(arguments().at(i));
} else if(arguments().at(i) == "-t" || arguments().at(i) == "--table") {
if(++i >= arguments().size())
qWarning() << qPrintable(tr("The -t/--table option requires an argument"));
else
tableToBrowse = arguments().at(i);
} else if(arguments().at(i) == "-q" || arguments().at(i) == "--quit") {
m_dontShowMainWindow = true;
} else if(arguments().at(i) == "-R" || arguments().at(i) == "--read-only") {
readOnly = true;
} else if(arguments().at(i) == "-o" || arguments().at(i) == "--option" ||
arguments().at(i) == "-O" || arguments().at(i) == "--save-option") {
const QString optionWarning = tr("The -o/--option and -O/--save-option options require an argument in the form group/setting=value");
bool saveToDisk = arguments().at(i) == "-O" || arguments().at(i) == "--save-option";
if(++i >= arguments().size())
qWarning() << qPrintable(optionWarning);
else {
QStringList option = arguments().at(i).split("=");
if (option.size() != 2)
qWarning() << qPrintable(optionWarning);
else {
QStringList setting = option.at(0).split("/");
if (setting.size() != 2)
qWarning() << qPrintable(optionWarning);
else {
QVariant value;
// Split string lists. This assumes they are always named "*list"
if (setting.at(1).endsWith("list", Qt::CaseInsensitive))
value = option.at(1).split(",");
else
value = option.at(1);
Settings::setValue(setting.at(0).toStdString(), setting.at(1).toStdString(), value, !saveToDisk);
}
}
}
} else {
// Other: Check if it's a valid file name
if(QFile::exists(arguments().at(i)))
fileToOpen = arguments().at(i);
else
qWarning() << qPrintable(tr("Invalid option/non-existant file: %1").arg(arguments().at(i)));
}
}
// Show main window
m_mainWindow = new MainWindow();
m_mainWindow->show();
connect(this, &Application::lastWindowClosed, this, &Application::quit);
// Open database if one was specified
if(fileToOpen.size())
{
if(m_mainWindow->fileOpen(fileToOpen, false, readOnly))
{
// If database could be opened run the SQL scripts
for(const QString& f : sqlToExecute)
{
QFile file(f);
if(file.open(QIODevice::ReadOnly))
{
m_mainWindow->getDb().executeMultiSQL(file.readAll(), false, true);
file.close();
}
}
if(!sqlToExecute.isEmpty())
m_mainWindow->refresh();
// Jump to table if the -t/--table parameter was set
if(!tableToBrowse.isEmpty())
m_mainWindow->switchToBrowseDataTab(sqlb::ObjectIdentifier("main", tableToBrowse.toStdString()));
}
}
}
Application::~Application()
{
delete m_mainWindow;
}
bool Application::event(QEvent* event)
{
switch(event->type())
{
case QEvent::FileOpen:
m_mainWindow->fileOpen(static_cast<QFileOpenEvent*>(event)->file());
return true;
default:
return QApplication::event(event);
}
}
QString Application::versionString()
{
// Nightly builds use a patch number of 99, and for these we include the build date in the version string. For
// our release versions (which use any other patch number) we don't include the build date. This should avoid
// confusion about what is more important, version number or build date, and about different build dates for
// the same version. This also should help making release builds reproducible out of the box.
#if PATCH_VERSION == 99
return QString("%1 (%2)").arg(APP_VERSION, __DATE__);
#else
return QString("%1").arg(APP_VERSION);
#endif
}
// Functions for documenting the shortcuts in the user interface using native names
static QString shortcutsTip(const QList<QKeySequence>& keys)
{
QString tip;
if (!keys.isEmpty()) {
tip = " [";
for (const auto& shortcut : keys)
tip.append(shortcut.toString(QKeySequence::NativeText) + ", ");
tip.chop(2);
tip.append("]");
}
return tip;
}
void addShortcutsTooltip(QAction* action, const QList<QKeySequence>& extraKeys)
{
if (!action->shortcuts().isEmpty() || !extraKeys.isEmpty())
action->setToolTip(action->toolTip() + shortcutsTip(action->shortcuts() + extraKeys));
}