From feda8a7db8d1d7c5439aa8f8feef7cc0dd2b59a0 Mon Sep 17 00:00:00 2001 From: Unit 193 Date: Fri, 27 Jul 2018 23:51:12 -0400 Subject: New upstream version 3.2.1+dfsg1 --- SQLiteStudio3/sqlitestudio/installscript.qs | 64 +++ SQLiteStudio3/sqlitestudio/main.cpp | 67 ++- SQLiteStudio3/sqlitestudio/package.xml | 17 + SQLiteStudio3/sqlitestudio/register_file_types.ui | 64 +++ .../singleapplication/singleapplication.cpp | 472 +++++++++++++++++++++ .../singleapplication/singleapplication.h | 135 ++++++ .../singleapplication/singleapplication_p.h | 85 ++++ SQLiteStudio3/sqlitestudio/sqlitestudio.pro | 43 +- SQLiteStudio3/sqlitestudio/sqlitestudio.qrc | 2 + .../sqlitestudio/translations/sqlitestudio_de.qm | Bin 2251 -> 2198 bytes .../sqlitestudio/translations/sqlitestudio_de.ts | 34 +- .../sqlitestudio/translations/sqlitestudio_es.ts | 36 +- .../sqlitestudio/translations/sqlitestudio_fr.qm | Bin 1824 -> 2323 bytes .../sqlitestudio/translations/sqlitestudio_fr.ts | 53 ++- .../sqlitestudio/translations/sqlitestudio_it.ts | 36 +- .../sqlitestudio/translations/sqlitestudio_pl.qm | Bin 2450 -> 2810 bytes .../sqlitestudio/translations/sqlitestudio_pl.ts | 6 +- .../translations/sqlitestudio_pt_BR.ts | 36 +- .../translations/sqlitestudio_ro_RO.qm | Bin 0 -> 30 bytes .../translations/sqlitestudio_ro_RO.ts | 82 ++++ .../sqlitestudio/translations/sqlitestudio_ru.qm | Bin 3002 -> 2949 bytes .../sqlitestudio/translations/sqlitestudio_ru.ts | 34 +- .../sqlitestudio/translations/sqlitestudio_sk.qm | Bin 834 -> 783 bytes .../sqlitestudio/translations/sqlitestudio_sk.ts | 34 +- .../translations/sqlitestudio_zh_CN.qm | Bin 406 -> 361 bytes .../translations/sqlitestudio_zh_CN.ts | 34 +- 26 files changed, 1121 insertions(+), 213 deletions(-) create mode 100644 SQLiteStudio3/sqlitestudio/installscript.qs create mode 100644 SQLiteStudio3/sqlitestudio/package.xml create mode 100644 SQLiteStudio3/sqlitestudio/register_file_types.ui create mode 100644 SQLiteStudio3/sqlitestudio/singleapplication/singleapplication.cpp create mode 100644 SQLiteStudio3/sqlitestudio/singleapplication/singleapplication.h create mode 100644 SQLiteStudio3/sqlitestudio/singleapplication/singleapplication_p.h create mode 100644 SQLiteStudio3/sqlitestudio/translations/sqlitestudio_ro_RO.qm create mode 100644 SQLiteStudio3/sqlitestudio/translations/sqlitestudio_ro_RO.ts (limited to 'SQLiteStudio3/sqlitestudio') diff --git a/SQLiteStudio3/sqlitestudio/installscript.qs b/SQLiteStudio3/sqlitestudio/installscript.qs new file mode 100644 index 0000000..8e6b84b --- /dev/null +++ b/SQLiteStudio3/sqlitestudio/installscript.qs @@ -0,0 +1,64 @@ +function Component() +{ + if (installer.value("os") === "win") { + component.loaded.connect(this, addOptionsCheckBoxForm); + component.fileTypes = ['db', 'db3', 'sqlite', 'sqlite3', 'sdb', 's3db']; + } +} + +addOptionsCheckBoxForm = function() +{ + // don't show when updating or uninstalling + if (installer.isInstaller()) { + installer.addWizardPageItem(component, "OptionsCheckBoxForm", QInstaller.TargetDirectory); + var form = component.userInterface("OptionsCheckBoxForm"); + + var assocCheckBox = form.RegisterFileCheckBox; + assocCheckBox.text = assocCheckBox.text + component.fileTypes.join(', '); + + var startMenuCheckbox = form.CreateStartMenuEntry; + startMenuCheckbox.stateChanged.connect(this, function() { + installer.setDefaultPageVisible(QInstaller.StartMenuSelection, startMenuCheckbox.checked); + }); + } +} + +Component.prototype.createOperations = function() +{ + // call default implementation to actually install the app + component.createOperations(); + + if (installer.value("os") === "win") { + var form = component.userInterface("OptionsCheckBoxForm"); + var isRegisterFileChecked = form.RegisterFileCheckBox.checked; + var isStartMenuEntryChecked = form.CreateStartMenuEntry.checked; + var forAllUsersChecked = form.CreateStartMenuEntry.ForAllUsers.checked; + + var executable = "@TargetDir@/SQLiteStudio.exe"; + + var linkPrefix = "@UserStartMenuProgramsPath@"; + if (forAllUsersChecked) { + linkPrefix = "@AllUsersStartMenuProgramsPath@"; + } + + if (isRegisterFileChecked) { + component.addOperation("CreateShortcut", executable, linkPrefix + "/@StartMenuDir@/SQLiteStudio.lnk", + "workingDirectory=@TargetDir@", "iconPath=@TargetDir@/SQLiteStudio.exe", + "iconId=0", "description=SQLiteStudio"); + } + + if (isRegisterFileChecked) { + component.fileTypes.forEach(function(fileType) { + component.addOperation( + "RegisterFileType", + fileType, + executable + " '%1'", + "SQLite database", + "application/octet-stream", + executable + ",0", + "ProgId=SQLiteStudio." + fileType + ); + }); + } + } +} diff --git a/SQLiteStudio3/sqlitestudio/main.cpp b/SQLiteStudio3/sqlitestudio/main.cpp index 829d657..443006b 100644 --- a/SQLiteStudio3/sqlitestudio/main.cpp +++ b/SQLiteStudio3/sqlitestudio/main.cpp @@ -26,6 +26,7 @@ #include "dialogs/languagedialog.h" #include "dialogs/triggerdialog.h" #include "services/pluginmanager.h" +#include "singleapplication/singleapplication.h" #include #include #include @@ -35,10 +36,14 @@ #include #include #include +#ifdef Q_OS_WIN +# include +# include +#endif static bool listPlugins = false; -QString uiHandleCmdLineArgs() +QString uiHandleCmdLineArgs(bool applyOptions = true) { QCommandLineParser parser; parser.setApplicationDescription(QObject::tr("GUI interface to SQLiteStudio, a SQLite manager.")); @@ -68,19 +73,22 @@ QString uiHandleCmdLineArgs() parser.process(qApp->arguments()); - bool enableDebug = parser.isSet(debugOption) || parser.isSet(debugStdOutOption) || parser.isSet(sqlDebugOption) || parser.isSet(debugFileOption); - setUiDebug(enableDebug, !parser.isSet(debugStdOutOption), parser.value(debugFileOption)); - CompletionHelper::enableLemonDebug = parser.isSet(lemonDebugOption); - setSqlLoggingEnabled(parser.isSet(sqlDebugOption)); - setExecutorLoggingEnabled(parser.isSet(executorDebugOption)); - if (parser.isSet(sqlDebugDbNameOption)) - setSqlLoggingFilter(parser.value(sqlDebugDbNameOption)); - - if (parser.isSet(listPluginsOption)) - listPlugins = true; - - if (parser.isSet(masterConfigOption)) - Config::setMasterConfigFile(parser.value(masterConfigOption)); + if (applyOptions) + { + bool enableDebug = parser.isSet(debugOption) || parser.isSet(debugStdOutOption) || parser.isSet(sqlDebugOption) || parser.isSet(debugFileOption); + setUiDebug(enableDebug, !parser.isSet(debugStdOutOption), parser.value(debugFileOption)); + CompletionHelper::enableLemonDebug = parser.isSet(lemonDebugOption); + setSqlLoggingEnabled(parser.isSet(sqlDebugOption)); + setExecutorLoggingEnabled(parser.isSet(executorDebugOption)); + if (parser.isSet(sqlDebugDbNameOption)) + setSqlLoggingFilter(parser.value(sqlDebugDbNameOption)); + + if (parser.isSet(listPluginsOption)) + listPlugins = true; + + if (parser.isSet(masterConfigOption)) + Config::setMasterConfigFile(parser.value(masterConfigOption)); + } QStringList args = parser.positionalArguments(); if (args.size() > 0) @@ -89,29 +97,18 @@ QString uiHandleCmdLineArgs() return QString::null; } -bool updateRetryFunction(const QString& msg) -{ - QMessageBox mb(QMessageBox::Critical, QObject::tr("Error"), msg); - mb.addButton(QMessageBox::Retry); - mb.addButton(QMessageBox::Abort); - return (mb.exec() == QMessageBox::Retry); -} - int main(int argc, char *argv[]) { - QApplication a(argc, argv); + SingleApplication a(argc, argv, true, SingleApplication::ExcludeAppPath|SingleApplication::ExcludeAppVersion); -#ifdef PORTABLE_CONFIG - int retCode = 1; - UpdateManager::setRetryFunction(updateRetryFunction); - if (UpdateManager::handleUpdateOptions(a.arguments(), retCode)) - { - if (retCode) - QMessageBox::critical(nullptr, QObject::tr("Error"), UpdateManager::getStaticErrorMessage()); - - return retCode; - } + if (a.isSecondary()) { +#ifdef Q_OS_WIN + AllowSetForegroundWindow(DWORD( a.primaryPid())); #endif + QString dbToOpen = uiHandleCmdLineArgs(); + a.sendMessage(serializeToBytes(dbToOpen)); + return 0; + } qInstallMessageHandler(uiMessageHandler); @@ -135,7 +132,9 @@ int main(int argc, char *argv[]) MultiEditorBool::staticInit(); TriggerDialog::staticInit(); - MainWindow::getInstance(); + MainWindow* mainWin = MAINWINDOW; + + QObject::connect(&a, &SingleApplication::receivedMessage, mainWin, &MainWindow::messageFromSecondaryInstance); SQLITESTUDIO->initPlugins(); diff --git a/SQLiteStudio3/sqlitestudio/package.xml b/SQLiteStudio3/sqlitestudio/package.xml new file mode 100644 index 0000000..1ac4203 --- /dev/null +++ b/SQLiteStudio3/sqlitestudio/package.xml @@ -0,0 +1,17 @@ + + + SQLiteStudio + SQLiteStudio core application + %VERSION% + %DATE% + pl.com.salsoft.sqlitestudio + io.qt + + + true + true + + + register_file_types.ui + + \ No newline at end of file diff --git a/SQLiteStudio3/sqlitestudio/register_file_types.ui b/SQLiteStudio3/sqlitestudio/register_file_types.ui new file mode 100644 index 0000000..24d896d --- /dev/null +++ b/SQLiteStudio3/sqlitestudio/register_file_types.ui @@ -0,0 +1,64 @@ + + + OptionsCheckBoxForm + + + + 0 + 0 + 400 + 300 + + + + Form + + + + 20 + + + + + Register following file extensions with SQLiteStudio: + + + + true + + + + + + + Create Start menu entry + + + true + + + + + + Create for current user only + + + true + + + + + + + Create for all users in the system + + + + + + + + + + + diff --git a/SQLiteStudio3/sqlitestudio/singleapplication/singleapplication.cpp b/SQLiteStudio3/sqlitestudio/singleapplication/singleapplication.cpp new file mode 100644 index 0000000..55d6853 --- /dev/null +++ b/SQLiteStudio3/sqlitestudio/singleapplication/singleapplication.cpp @@ -0,0 +1,472 @@ +// The MIT License (MIT) +// +// Copyright (c) Itay Grudev 2015 - 2016 +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define SINGLE_APP_STREAM_VERSION QDataStream::Qt_5_3 + +#ifdef Q_OS_UNIX + #include + #include +#endif + +#ifdef Q_OS_WIN + #include + #include +#endif + +#include "singleapplication.h" +#include "singleapplication_p.h" + + +SingleApplicationPrivate::SingleApplicationPrivate( SingleApplication *q_ptr ) : q_ptr( q_ptr ) { + server = nullptr; + socket = nullptr; +} + +SingleApplicationPrivate::~SingleApplicationPrivate() +{ + if( socket != nullptr ) { + socket->close(); + delete socket; + } + + memory->lock(); + InstancesInfo* inst = static_cast(memory->data()); + if( server != nullptr ) { + server->close(); + delete server; + inst->primary = false; + inst->primaryPid = -1; + } + memory->unlock(); + + delete memory; +} + +void SingleApplicationPrivate::genBlockServerName( int timeout ) +{ + QCryptographicHash appData( QCryptographicHash::Sha256 ); + appData.addData( "SingleApplication", 17 ); + appData.addData( SingleApplication::app_t::applicationName().toUtf8() ); + appData.addData( SingleApplication::app_t::organizationName().toUtf8() ); + appData.addData( SingleApplication::app_t::organizationDomain().toUtf8() ); + + if( ! (options & SingleApplication::Mode::ExcludeAppVersion) ) { + appData.addData( SingleApplication::app_t::applicationVersion().toUtf8() ); + } + + if( ! (options & SingleApplication::Mode::ExcludeAppPath) ) { +#ifdef Q_OS_WIN + appData.addData( SingleApplication::app_t::applicationFilePath().toLower().toUtf8() ); +#else + appData.addData( SingleApplication::app_t::applicationFilePath().toUtf8() ); +#endif + } + + // User level block requires a user specific data in the hash + if( options & SingleApplication::Mode::User ) { +#ifdef Q_OS_WIN + Q_UNUSED(timeout); + wchar_t username [ UNLEN + 1 ]; + // Specifies size of the buffer on input + DWORD usernameLength = UNLEN + 1; + if( GetUserNameW( username, &usernameLength ) ) { + appData.addData( QString::fromWCharArray(username).toUtf8() ); + } else { + appData.addData( QStandardPaths::standardLocations( QStandardPaths::HomeLocation ).join("").toUtf8() ); + } +#endif +#ifdef Q_OS_UNIX + QProcess process; + process.start( "whoami" ); + if( process.waitForFinished( timeout ) && + process.exitCode() == QProcess::NormalExit) { + appData.addData( process.readLine() ); + } else { + appData.addData( + QDir( + QStandardPaths::standardLocations( QStandardPaths::HomeLocation ).first() + ).absolutePath().toUtf8() + ); + } +#endif + } + + // Replace the backslash in RFC 2045 Base64 [a-zA-Z0-9+/=] to comply with + // server naming requirements. + blockServerName = appData.result().toBase64().replace("/", "_"); +} + +void SingleApplicationPrivate::startPrimary( bool resetMemory ) +{ + Q_Q(SingleApplication); + +#ifdef Q_OS_UNIX + // Handle any further termination signals to ensure the + // QSharedMemory block is deleted even if the process crashes + crashHandler(); +#endif + // Successful creation means that no main process exists + // So we start a QLocalServer to listen for connections + QLocalServer::removeServer( blockServerName ); + server = new QLocalServer(); + + // Restrict access to the socket according to the + // SingleApplication::Mode::User flag on User level or no restrictions + if( options & SingleApplication::Mode::User ) { + server->setSocketOptions( QLocalServer::UserAccessOption ); + } else { + server->setSocketOptions( QLocalServer::WorldAccessOption ); + } + + server->listen( blockServerName ); + QObject::connect( + server, + &QLocalServer::newConnection, + this, + &SingleApplicationPrivate::slotConnectionEstablished + ); + + // Reset the number of connections + memory->lock(); + InstancesInfo* inst = static_cast(memory->data()); + + if( resetMemory ) { + inst->secondary = 0; + } + + inst->primary = true; + inst->primaryPid = q->applicationPid(); + + memory->unlock(); + + instanceNumber = 0; +} + +void SingleApplicationPrivate::startSecondary() +{ +#ifdef Q_OS_UNIX + // Handle any further termination signals to ensure the + // QSharedMemory block is deleted even if the process crashes + crashHandler(); +#endif +} + +void SingleApplicationPrivate::connectToPrimary( int msecs, ConnectionType connectionType ) +{ + // Connect to the Local Server of the Primary Instance if not already + // connected. + if( socket == nullptr ) { + socket = new QLocalSocket(); + } + + // If already connected - we are done; + if( socket->state() == QLocalSocket::ConnectedState ) + return; + + // If not connect + if( socket->state() == QLocalSocket::UnconnectedState || + socket->state() == QLocalSocket::ClosingState ) { + socket->connectToServer( blockServerName ); + } + + // Wait for being connected + if( socket->state() == QLocalSocket::ConnectingState ) { + socket->waitForConnected( msecs ); + } + + // Initialisation message according to the SingleApplication protocol + if( socket->state() == QLocalSocket::ConnectedState ) { + // Notify the parent that a new instance had been started; + QByteArray initMsg; + QDataStream writeStream(&initMsg, QIODevice::WriteOnly); + writeStream.setVersion(SINGLE_APP_STREAM_VERSION); + writeStream << blockServerName.toLatin1(); + writeStream << static_cast(connectionType); + writeStream << instanceNumber; + quint16 checksum = qChecksum(initMsg.constData(), static_cast(initMsg.length())); + writeStream << checksum; + + socket->write( initMsg ); + socket->flush(); + socket->waitForBytesWritten( msecs ); + } +} + +qint64 SingleApplicationPrivate::primaryPid() +{ + qint64 pid; + + memory->lock(); + InstancesInfo* inst = static_cast(memory->data()); + pid = inst->primaryPid; + memory->unlock(); + + return pid; +} + +#ifdef Q_OS_UNIX + void SingleApplicationPrivate::crashHandler() + { + // Handle any further termination signals to ensure the + // QSharedMemory block is deleted even if the process crashes + signal( SIGHUP, SingleApplicationPrivate::terminate ); // 1 + signal( SIGINT, SingleApplicationPrivate::terminate ); // 2 + signal( SIGQUIT, SingleApplicationPrivate::terminate ); // 3 + signal( SIGILL, SingleApplicationPrivate::terminate ); // 4 + signal( SIGABRT, SingleApplicationPrivate::terminate ); // 6 + signal( SIGFPE, SingleApplicationPrivate::terminate ); // 8 + signal( SIGBUS, SingleApplicationPrivate::terminate ); // 10 + signal( SIGSEGV, SingleApplicationPrivate::terminate ); // 11 + signal( SIGSYS, SingleApplicationPrivate::terminate ); // 12 + signal( SIGPIPE, SingleApplicationPrivate::terminate ); // 13 + signal( SIGALRM, SingleApplicationPrivate::terminate ); // 14 + signal( SIGTERM, SingleApplicationPrivate::terminate ); // 15 + signal( SIGXCPU, SingleApplicationPrivate::terminate ); // 24 + signal( SIGXFSZ, SingleApplicationPrivate::terminate ); // 25 + } + + void SingleApplicationPrivate::terminate( int signum ) + { + delete ((SingleApplication*)QCoreApplication::instance())->d_ptr; + ::exit( 128 + signum ); + } +#endif + +/** + * @brief Executed when a connection has been made to the LocalServer + */ +void SingleApplicationPrivate::slotConnectionEstablished() +{ + Q_Q(SingleApplication); + + QLocalSocket *nextConnSocket = server->nextPendingConnection(); + + quint32 instanceId = 0; + ConnectionType connectionType = InvalidConnection; + if( nextConnSocket->waitForReadyRead( 100 ) ) { + // read all data from message in same order/format as written + QByteArray msgBytes = nextConnSocket->read(nextConnSocket->bytesAvailable() - static_cast(sizeof(quint16))); + QByteArray checksumBytes = nextConnSocket->read(sizeof(quint16)); + QDataStream readStream(msgBytes); + readStream.setVersion(SINGLE_APP_STREAM_VERSION); + + // server name + QByteArray latin1Name; + readStream >> latin1Name; + // connectioon type + quint8 connType = InvalidConnection; + readStream >> connType; + connectionType = static_cast(connType); + // instance id + readStream >> instanceId; + // checksum + quint16 msgChecksum = 0; + QDataStream checksumStream(checksumBytes); + checksumStream.setVersion(SINGLE_APP_STREAM_VERSION); + checksumStream >> msgChecksum; + + const quint16 actualChecksum = qChecksum(msgBytes.constData(), static_cast(msgBytes.length())); + + if (readStream.status() != QDataStream::Ok || QLatin1String(latin1Name) != blockServerName || msgChecksum != actualChecksum) { + connectionType = InvalidConnection; + } + } + + if( connectionType == InvalidConnection ) { + nextConnSocket->close(); + delete nextConnSocket; + return; + } + + QObject::connect( + nextConnSocket, + &QLocalSocket::aboutToClose, + this, + [nextConnSocket, instanceId, this]() { + Q_EMIT this->slotClientConnectionClosed( nextConnSocket, instanceId ); + } + ); + + QObject::connect( + nextConnSocket, + &QLocalSocket::readyRead, + this, + [nextConnSocket, instanceId, this]() { + Q_EMIT this->slotDataAvailable( nextConnSocket, instanceId ); + } + ); + + if( connectionType == NewInstance || ( + connectionType == SecondaryInstance && + options & SingleApplication::Mode::SecondaryNotification + ) + ) { + Q_EMIT q->instanceStarted(); + } + + if( nextConnSocket->bytesAvailable() > 0 ) { + Q_EMIT this->slotDataAvailable( nextConnSocket, instanceId ); + } +} + +void SingleApplicationPrivate::slotDataAvailable( QLocalSocket *dataSocket, quint32 instanceId ) +{ + Q_Q(SingleApplication); + Q_EMIT q->receivedMessage( instanceId, dataSocket->readAll() ); +} + +void SingleApplicationPrivate::slotClientConnectionClosed( QLocalSocket *closedSocket, quint32 instanceId ) +{ + if( closedSocket->bytesAvailable() > 0 ) + Q_EMIT slotDataAvailable( closedSocket, instanceId ); + closedSocket->deleteLater(); +} + +/** + * @brief Constructor. Checks and fires up LocalServer or closes the program + * if another instance already exists + * @param argc + * @param argv + * @param {bool} allowSecondaryInstances + */ +SingleApplication::SingleApplication( int &argc, char *argv[], bool allowSecondary, Options options, int timeout ) + : app_t( argc, argv ), d_ptr( new SingleApplicationPrivate( this ) ) +{ + Q_D(SingleApplication); + + // Store the current mode of the program + d->options = options; + + // Generating an application ID used for identifying the shared memory + // block and QLocalServer + d->genBlockServerName( timeout ); + + // Guarantee thread safe behaviour with a shared memory block. Also by + // explicitly attaching it and then deleting it we make sure that the + // memory is deleted even if the process had crashed on Unix. +#ifdef Q_OS_UNIX + d->memory = new QSharedMemory( d->blockServerName ); + d->memory->attach(); + delete d->memory; +#endif + d->memory = new QSharedMemory( d->blockServerName ); + + // Create a shared memory block + if( d->memory->create( sizeof( InstancesInfo ) ) ) { + d->startPrimary( true ); + return; + } else { + // Attempt to attach to the memory segment + if( d->memory->attach() ) { + d->memory->lock(); + InstancesInfo* inst = static_cast(d->memory->data()); + + if( ! inst->primary ) { + d->startPrimary( false ); + d->memory->unlock(); + return; + } + + // Check if another instance can be started + if( allowSecondary ) { + inst->secondary += 1; + d->instanceNumber = inst->secondary; + d->startSecondary(); + if( d->options & Mode::SecondaryNotification ) { + d->connectToPrimary( timeout, SingleApplicationPrivate::SecondaryInstance ); + } + d->memory->unlock(); + return; + } + + d->memory->unlock(); + } + } + + d->connectToPrimary( timeout, SingleApplicationPrivate::NewInstance ); + delete d; + ::exit( EXIT_SUCCESS ); +} + +/** + * @brief Destructor + */ +SingleApplication::~SingleApplication() +{ + Q_D(SingleApplication); + delete d; +} + +bool SingleApplication::isPrimary() +{ + Q_D(SingleApplication); + return d->server != nullptr; +} + +bool SingleApplication::isSecondary() +{ + Q_D(SingleApplication); + return d->server == nullptr; +} + +quint32 SingleApplication::instanceId() +{ + Q_D(SingleApplication); + return d->instanceNumber; +} + +qint64 SingleApplication::primaryPid() +{ + Q_D(SingleApplication); + return d->primaryPid(); +} + +bool SingleApplication::sendMessage( QByteArray message, int timeout ) +{ + Q_D(SingleApplication); + + // Nobody to connect to + if( isPrimary() ) return false; + + // Make sure the socket is connected + d->connectToPrimary( timeout, SingleApplicationPrivate::Reconnect ); + QThread::msleep(100); + + d->socket->write( message ); + bool dataWritten = d->socket->flush(); + d->socket->waitForBytesWritten( timeout ); + return dataWritten; +} diff --git a/SQLiteStudio3/sqlitestudio/singleapplication/singleapplication.h b/SQLiteStudio3/sqlitestudio/singleapplication/singleapplication.h new file mode 100644 index 0000000..33a9898 --- /dev/null +++ b/SQLiteStudio3/sqlitestudio/singleapplication/singleapplication.h @@ -0,0 +1,135 @@ +// The MIT License (MIT) +// +// Copyright (c) Itay Grudev 2015 - 2016 +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef SINGLE_APPLICATION_H +#define SINGLE_APPLICATION_H + +#include +#include + +#ifndef QAPPLICATION_CLASS + #define QAPPLICATION_CLASS QCoreApplication +#endif + +#include QT_STRINGIFY(QAPPLICATION_CLASS) + +class SingleApplicationPrivate; + +/** + * @brief The SingleApplication class handles multipe instances of the same + * Application + * @see QCoreApplication + */ +class SingleApplication : public QAPPLICATION_CLASS +{ + Q_OBJECT + + typedef QAPPLICATION_CLASS app_t; + +public: + /** + * @brief Mode of operation of SingleApplication. + * Whether the block should be user-wide or system-wide and whether the + * primary instance should be notified when a secondary instance had been + * started. + * @note Operating system can restrict the shared memory blocks to the same + * user, in which case the User/System modes will have no effect and the + * block will be user wide. + * @enum + */ + enum Mode { + User = 1 << 0, + System = 1 << 1, + SecondaryNotification = 1 << 2, + ExcludeAppVersion = 1 << 3, + ExcludeAppPath = 1 << 4 + }; + Q_DECLARE_FLAGS(Options, Mode) + + /** + * @brief Intitializes a SingleApplication instance with argc command line + * arguments in argv + * @arg {int &} argc - Number of arguments in argv + * @arg {const char *[]} argv - Supplied command line arguments + * @arg {bool} allowSecondary - Whether to start the instance as secondary + * if there is already a primary instance. + * @arg {Mode} mode - Whether for the SingleApplication block to be applied + * User wide or System wide. + * @arg {int} timeout - Timeout to wait in miliseconds. + * @note argc and argv may be changed as Qt removes arguments that it + * recognizes + * @note Mode::SecondaryNotification only works if set on both the primary + * instance and the secondary instance. + * @note The timeout is just a hint for the maximum time of blocking + * operations. It does not guarantee that the SingleApplication + * initialisation will be completed in given time, though is a good hint. + * Usually 4*timeout would be the worst case (fail) scenario. + * @see See the corresponding QAPPLICATION_CLASS constructor for reference + */ + explicit SingleApplication( int &argc, char *argv[], bool allowSecondary = false, Options options = Mode::User, int timeout = 100 ); + ~SingleApplication(); + + /** + * @brief Returns if the instance is the primary instance + * @returns {bool} + */ + bool isPrimary(); + + /** + * @brief Returns if the instance is a secondary instance + * @returns {bool} + */ + bool isSecondary(); + + /** + * @brief Returns a unique identifier for the current instance + * @returns {qint32} + */ + quint32 instanceId(); + + /** + * @brief Returns the process ID (PID) of the primary instance + * @returns {qint64} + */ + qint64 primaryPid(); + + /** + * @brief Sends a message to the primary instance. Returns true on success. + * @param {int} timeout - Timeout for connecting + * @returns {bool} + * @note sendMessage() will return false if invoked from the primary + * instance. + */ + bool sendMessage( QByteArray message, int timeout = 100 ); + +Q_SIGNALS: + void instanceStarted(); + void receivedMessage( quint32 instanceId, QByteArray message ); + +private: + SingleApplicationPrivate *d_ptr; + Q_DECLARE_PRIVATE(SingleApplication) +}; + +Q_DECLARE_OPERATORS_FOR_FLAGS(SingleApplication::Options) + +#endif // SINGLE_APPLICATION_H diff --git a/SQLiteStudio3/sqlitestudio/singleapplication/singleapplication_p.h b/SQLiteStudio3/sqlitestudio/singleapplication/singleapplication_p.h new file mode 100644 index 0000000..a990a53 --- /dev/null +++ b/SQLiteStudio3/sqlitestudio/singleapplication/singleapplication_p.h @@ -0,0 +1,85 @@ +// The MIT License (MIT) +// +// Copyright (c) Itay Grudev 2015 - 2016 +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +// +// W A R N I N G !!! +// ----------------- +// +// This file is not part of the SingleApplication API. It is used purely as an +// implementation detail. This header file may change from version to +// version without notice, or may even be removed. +// + +#ifndef SINGLEAPPLICATION_P_H +#define SINGLEAPPLICATION_P_H + +#include +#include +#include +#include "singleapplication.h" + +struct InstancesInfo { + bool primary; + quint32 secondary; + qint64 primaryPid; +}; + +class SingleApplicationPrivate : public QObject { +Q_OBJECT +public: + enum ConnectionType : quint8 { + InvalidConnection = 0, + NewInstance = 1, + SecondaryInstance = 2, + Reconnect = 3 + }; + Q_DECLARE_PUBLIC(SingleApplication) + + SingleApplicationPrivate( SingleApplication *q_ptr ); + ~SingleApplicationPrivate(); + + void genBlockServerName( int msecs ); + void startPrimary( bool resetMemory ); + void startSecondary(); + void connectToPrimary(int msecs, ConnectionType connectionType ); + qint64 primaryPid(); + +#ifdef Q_OS_UNIX + void crashHandler(); + static void terminate( int signum ); +#endif + + QSharedMemory *memory; + SingleApplication *q_ptr; + QLocalSocket *socket; + QLocalServer *server; + quint32 instanceNumber; + QString blockServerName; + SingleApplication::Options options; + +public Q_SLOTS: + void slotConnectionEstablished(); + void slotDataAvailable( QLocalSocket*, quint32 ); + void slotClientConnectionClosed( QLocalSocket*, quint32 ); +}; + +#endif // SINGLEAPPLICATION_P_H diff --git a/SQLiteStudio3/sqlitestudio/sqlitestudio.pro b/SQLiteStudio3/sqlitestudio/sqlitestudio.pro index 42aa7dc..96d9f0d 100644 --- a/SQLiteStudio3/sqlitestudio/sqlitestudio.pro +++ b/SQLiteStudio3/sqlitestudio/sqlitestudio.pro @@ -4,9 +4,7 @@ # #------------------------------------------------- -QT += core gui - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets +QT += core gui widgets network include($$PWD/../dirs.pri) include($$PWD/../utils.pri) @@ -15,25 +13,37 @@ OBJECTS_DIR = $$OBJECTS_DIR/sqlitestudio MOC_DIR = $$MOC_DIR/sqlitestudio UI_DIR = $$UI_DIR/sqlitestudio -linux: { +linux { TARGET = sqlitestudio -} -!linux: { +} else { TARGET = SQLiteStudio } TEMPLATE = app CONFIG += c++11 QMAKE_CXXFLAGS += -pedantic -linux|portable { - QMAKE_LFLAGS += -Wl,-rpath,./lib + +DEFINES += QAPPLICATION_CLASS=QApplication + +win32 { + msvc:LIBS += Advapi32.lib + gcc:LIBS += -lAdvapi32 +} + +portable { + DEFINES += PORTABLE_CONFIG + linux { + QMAKE_LFLAGS += -Wl,-rpath,./lib + } } LIBS += -lcoreSQLiteStudio -lguiSQLiteStudio -SOURCES += main.cpp +SOURCES += main.cpp \ + singleapplication/singleapplication.cpp -TRANSLATIONS += translations/sqlitestudio_de.ts \ +TRANSLATIONS += translations/sqlitestudio_ro_RO.ts \ + translations/sqlitestudio_de.ts \ translations/sqlitestudio_it.ts \ translations/sqlitestudio_zh_CN.ts \ translations/sqlitestudio_sk.ts \ @@ -43,11 +53,13 @@ TRANSLATIONS += translations/sqlitestudio_de.ts \ translations/sqlitestudio_es.ts \ translations/sqlitestudio_pl.ts -win32: { +win32 { RC_FILE = windows.rc + msvc:LIBS += User32.lib + gcc:LIBS += -lUser32 } -macx: { +macx { ICON = ../guiSQLiteStudio/img/sqlitestudio.icns } @@ -55,7 +67,7 @@ OTHER_FILES += \ windows.rc \ SQLiteStudio.exe.manifest -unix: { +unix { target.path = $$BINDIR INSTALLS += target } @@ -63,6 +75,11 @@ unix: { RESOURCES += \ sqlitestudio.qrc +HEADERS += \ + singleapplication/singleapplication.h \ + singleapplication/singleapplication_p.h + + diff --git a/SQLiteStudio3/sqlitestudio/sqlitestudio.qrc b/SQLiteStudio3/sqlitestudio/sqlitestudio.qrc index 9942536..6431227 100644 --- a/SQLiteStudio3/sqlitestudio/sqlitestudio.qrc +++ b/SQLiteStudio3/sqlitestudio/sqlitestudio.qrc @@ -1,5 +1,6 @@ + translations/sqlitestudio_ro_RO.qm translations/sqlitestudio_de.qm translations/sqlitestudio_pl.qm translations/sqlitestudio_ru.qm @@ -11,3 +12,4 @@ + diff --git a/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_de.qm b/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_de.qm index 6007538..b319573 100644 Binary files a/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_de.qm and b/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_de.qm differ diff --git a/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_de.ts b/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_de.ts index fb20723..a65829c 100644 --- a/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_de.ts +++ b/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_de.ts @@ -4,87 +4,85 @@ QObject - + GUI interface to SQLiteStudio, a SQLite manager. GUI Schnittstelle zu SQLiteStudio, ein SQLite Manager. - + Enables debug messages in console (accessible with F12). Aktiviert Debug-Meldungen in der Konsole (erreichbar über F12). - + Redirects debug messages into standard output (forces debug mode). Leitet Debug-Meldungen in den Standardausgabekanal um (erzwingt den Debugmodus). - + Redirects debug messages into given file (forces debug mode). Leitet Debug-Meldungen in die angegebene Datei um (erzwingt den Debugmodus). - + log file Logdatei - + Enables Lemon parser debug messages for SQL code assistant. Aktiviert Lemon Parser Debug-Meldungen für den SQL Codeassistenten. - + Enables debugging of every single SQL query being sent to any database. Aktiviert das Debugging für jede SQL Abfrage, die an eine beliebige Datenbank gesendet wurde. - + Limits SQL query messages to only the given <database>. Wird <database> bei Ausgabe der Meldung in die aktuelle Datenbankbezeichnung umgewandelt? Begrenzt SQL Abfragemeldungen auf folgende Datenbank: <database>. - + database Datenbank - + Enables debugging of SQLiteStudio's query executor. - + Lists plugins installed in the SQLiteStudio and quits. Was wird hier beendet? Listet die in SQLiteStudio installierten Plugins auf und beendet. - + Points to the master configuration file. Read manual at wiki page for more details. - + SQLiteStudio settings file - + file Datei - + Database file to open Zu öffnende Datenbankdatei - - Error - Fehler + Fehler diff --git a/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_es.ts b/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_es.ts index d58025f..ff56801 100644 --- a/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_es.ts +++ b/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_es.ts @@ -4,85 +4,79 @@ QObject - + GUI interface to SQLiteStudio, a SQLite manager. - + Enables debug messages in console (accessible with F12). - + Redirects debug messages into standard output (forces debug mode). - + Redirects debug messages into given file (forces debug mode). - + log file - + Enables Lemon parser debug messages for SQL code assistant. - + Enables debugging of every single SQL query being sent to any database. - + Limits SQL query messages to only the given <database>. - + database - + Enables debugging of SQLiteStudio's query executor. - + Lists plugins installed in the SQLiteStudio and quits. - + Points to the master configuration file. Read manual at wiki page for more details. - + SQLiteStudio settings file - + file - + Database file to open - - - - Error - - diff --git a/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_fr.qm b/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_fr.qm index 9d59c25..de3c6d6 100644 Binary files a/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_fr.qm and b/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_fr.qm differ diff --git a/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_fr.ts b/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_fr.ts index fc7e350..087d5b8 100644 --- a/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_fr.ts +++ b/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_fr.ts @@ -4,86 +4,83 @@ QObject - + GUI interface to SQLiteStudio, a SQLite manager. - Interface GUI de SQLiteStudio un outil pour SQLite - + Interface GUI de SQLiteStudio, un outil pour SQLite. - + Enables debug messages in console (accessible with F12). - Messages de déboguage avec la console(accessible avec F12). + Messages de déboguage dans la console (accessible avec F12). - + Redirects debug messages into standard output (forces debug mode). - Messages de déboguage redirigés vers sortie standard(mode déboguage forcé). + Messages de déboguage redirigés vers sortie standard (mode déboguage forcé). - + Redirects debug messages into given file (forces debug mode). - + Messages de déboguage redirigés vers un fichier (mode déboguage forcé). - + log file - + fichier log - + Enables Lemon parser debug messages for SQL code assistant. Message de déboguage avec l’analyseur Lemon pour un assistant code SQL. - + Enables debugging of every single SQL query being sent to any database. - Déboguage pour toutes requêtes SQL simple utilisé pour la plupart des bases de données. + Déboguage pour chaque requête SQL envoyée à toute base de données. - + Limits SQL query messages to only the given <database>. - Limites des meesages de la requête SQL pour la <database>. + Limite les messages de la requête SQL à la <database>. - + database Base de données - + Enables debugging of SQLiteStudio's query executor. - + Déboguage de l'exécuteur de requêtes de SQLiteStudio. - + Lists plugins installed in the SQLiteStudio and quits. - Listes des plugins installés dans SQLiteStudio et quitter. + Liste les plugins installés dans SQLiteStudio et quitte. - + Points to the master configuration file. Read manual at wiki page for more details. - + SQLiteStudio settings file - + file Fichier - + Database file to open Fichier de la base de données à ouvrir - - Error - Erreur + Erreur diff --git a/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_it.ts b/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_it.ts index 88ce9ce..ef01351 100644 --- a/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_it.ts +++ b/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_it.ts @@ -4,85 +4,79 @@ QObject - + GUI interface to SQLiteStudio, a SQLite manager. - + Enables debug messages in console (accessible with F12). - + Redirects debug messages into standard output (forces debug mode). - + Redirects debug messages into given file (forces debug mode). - + log file - + Enables Lemon parser debug messages for SQL code assistant. - + Enables debugging of every single SQL query being sent to any database. - + Limits SQL query messages to only the given <database>. - + database - + Enables debugging of SQLiteStudio's query executor. - + Lists plugins installed in the SQLiteStudio and quits. - + Points to the master configuration file. Read manual at wiki page for more details. - + SQLiteStudio settings file - + file - + Database file to open - - - - Error - - diff --git a/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_pl.qm b/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_pl.qm index df5348b..b444825 100644 Binary files a/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_pl.qm and b/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_pl.qm differ diff --git a/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_pl.ts b/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_pl.ts index 365a823..0add178 100644 --- a/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_pl.ts +++ b/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_pl.ts @@ -41,7 +41,7 @@ Error - Błąd + Błąd Lists plugins installed in the SQLiteStudio and quits. @@ -61,11 +61,11 @@ Points to the master configuration file. Read manual at wiki page for more details. - + Wskazuje na główny plik konfiguracyjny. Więcej szczegółów w podręczniku na stronie wiki. SQLiteStudio settings file - + Plik ustawień SQLiteStudio diff --git a/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_pt_BR.ts b/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_pt_BR.ts index 95025b4..23c60cc 100644 --- a/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_pt_BR.ts +++ b/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_pt_BR.ts @@ -4,85 +4,79 @@ QObject - + GUI interface to SQLiteStudio, a SQLite manager. - + Enables debug messages in console (accessible with F12). - + Redirects debug messages into standard output (forces debug mode). - + Redirects debug messages into given file (forces debug mode). - + log file - + Enables Lemon parser debug messages for SQL code assistant. - + Enables debugging of every single SQL query being sent to any database. - + Limits SQL query messages to only the given <database>. - + database - + Enables debugging of SQLiteStudio's query executor. - + Lists plugins installed in the SQLiteStudio and quits. - + Points to the master configuration file. Read manual at wiki page for more details. - + SQLiteStudio settings file - + file - + Database file to open - - - - Error - - diff --git a/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_ro_RO.qm b/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_ro_RO.qm new file mode 100644 index 0000000..2856eb9 Binary files /dev/null and b/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_ro_RO.qm differ diff --git a/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_ro_RO.ts b/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_ro_RO.ts new file mode 100644 index 0000000..b4b3802 --- /dev/null +++ b/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_ro_RO.ts @@ -0,0 +1,82 @@ + + + + + QObject + + + GUI interface to SQLiteStudio, a SQLite manager. + + + + + Enables debug messages in console (accessible with F12). + + + + + Redirects debug messages into standard output (forces debug mode). + + + + + Redirects debug messages into given file (forces debug mode). + + + + + log file + + + + + Enables Lemon parser debug messages for SQL code assistant. + + + + + Enables debugging of every single SQL query being sent to any database. + + + + + Limits SQL query messages to only the given <database>. + + + + + database + + + + + Enables debugging of SQLiteStudio's query executor. + + + + + Lists plugins installed in the SQLiteStudio and quits. + + + + + Points to the master configuration file. Read manual at wiki page for more details. + + + + + SQLiteStudio settings file + + + + + file + + + + + Database file to open + + + + diff --git a/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_ru.qm b/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_ru.qm index b5a73d2..5541fe4 100644 Binary files a/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_ru.qm and b/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_ru.qm differ diff --git a/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_ru.ts b/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_ru.ts index 65f0cf4..f9d2eae 100644 --- a/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_ru.ts +++ b/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_ru.ts @@ -4,85 +4,83 @@ QObject - + GUI interface to SQLiteStudio, a SQLite manager. Графический интерфейс для SQLiteStudio, менеджера баз данных SQLite. - + Enables debug messages in console (accessible with F12). Включает вывод отладочных сообщений в консоль (доступную по нажатию F12). - + Redirects debug messages into standard output (forces debug mode). Перенаправляет отладочные сообщения в стандартный поток (принудительный отладочный режим). - + Redirects debug messages into given file (forces debug mode). Перенаправляет отладочные сообщения в указанный файл (принудительный отладочный режим). - + log file файл журнала - + Enables Lemon parser debug messages for SQL code assistant. Включает вывод отладочных сообщений анализатора Lemon для автодополнения SQL кода. - + Enables debugging of every single SQL query being sent to any database. Включает отладку каждого запроса SQL, посылаемого к любой базе данных. - + Limits SQL query messages to only the given <database>. Ограничивает сообщения запросов SQL только для указанной <базы данных>. - + database база данных - + Enables debugging of SQLiteStudio's query executor. Включает отладку обработчика запросов SQLiteStudio. - + Lists plugins installed in the SQLiteStudio and quits. Выводит список установленных в SQLiteStudio модулей и осуществляет выход. - + Points to the master configuration file. Read manual at wiki page for more details. Указывает основной файл конфигурации. Детальная информация содержится в инструкции на wiki-странице. - + SQLiteStudio settings file Файл настроек SQLiteStudio - + file файл - + Database file to open Файл базы данных для открытия - - Error - Ошибка + Ошибка diff --git a/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_sk.qm b/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_sk.qm index 526751e..01f60b5 100644 Binary files a/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_sk.qm and b/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_sk.qm differ diff --git a/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_sk.ts b/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_sk.ts index 6c08225..d1ec165 100644 --- a/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_sk.ts +++ b/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_sk.ts @@ -4,85 +4,83 @@ QObject - + GUI interface to SQLiteStudio, a SQLite manager. GUI rozhranie pre SQLiteStudio, SQLite manažér. - + Enables debug messages in console (accessible with F12). Aktivuje ladiace správy v konzole (dostupné pomocou F12). - + Redirects debug messages into standard output (forces debug mode). Presmerovať ladiace informácie na štandardný výstup (vynútený ladiaci mód). - + Redirects debug messages into given file (forces debug mode). - + log file - + Enables Lemon parser debug messages for SQL code assistant. - + Enables debugging of every single SQL query being sent to any database. - + Limits SQL query messages to only the given <database>. - + database databáza - + Enables debugging of SQLiteStudio's query executor. - + Lists plugins installed in the SQLiteStudio and quits. - + Points to the master configuration file. Read manual at wiki page for more details. - + SQLiteStudio settings file - + file Súbor - + Database file to open - - Error - Chyba + Chyba diff --git a/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_zh_CN.qm b/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_zh_CN.qm index 83692c1..83024d2 100644 Binary files a/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_zh_CN.qm and b/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_zh_CN.qm differ diff --git a/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_zh_CN.ts b/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_zh_CN.ts index 0417421..b84ae66 100644 --- a/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_zh_CN.ts +++ b/SQLiteStudio3/sqlitestudio/translations/sqlitestudio_zh_CN.ts @@ -4,85 +4,83 @@ QObject - + GUI interface to SQLiteStudio, a SQLite manager. - + Enables debug messages in console (accessible with F12). - + Redirects debug messages into standard output (forces debug mode). - + Redirects debug messages into given file (forces debug mode). - + log file 日志文件 - + Enables Lemon parser debug messages for SQL code assistant. - + Enables debugging of every single SQL query being sent to any database. - + Limits SQL query messages to only the given <database>. - + database 数据库 - + Enables debugging of SQLiteStudio's query executor. - + Lists plugins installed in the SQLiteStudio and quits. 列出已安装的插件并退出。 - + Points to the master configuration file. Read manual at wiki page for more details. - + SQLiteStudio settings file - + file 文件 - + Database file to open 要打开的数据库文件 - - Error - 错误 + 错误 -- cgit v1.2.3