Esempio n. 1
0
void migrateConfigToAppDir()
{
    const QString appDir = QCoreApplication::applicationDirPath();
    const QString path = appDir + "/config";
    const QString uninstPath = appDir + "/unins000.exe";
    QDir dir(path);

    if ( !QFile::exists(uninstPath)
         && QFileInfo(appDir).isWritable()
         && dir.mkpath("copyq")
         && dir.cd("copyq")
         && dir.isReadable()
         && QFileInfo(dir.absolutePath()).isWritable() )
    {
        QSettings oldSettings;
        const QString oldConfigFileName =
                QSettings(QSettings::IniFormat, QSettings::UserScope,
                          QCoreApplication::organizationName(),
                          QCoreApplication::applicationName()).fileName();
        const QString oldConfigPath = QDir::cleanPath(oldConfigFileName + "/..");

        QSettings::setPath(QSettings::IniFormat, QSettings::UserScope, path);
        QSettings::setDefaultFormat(QSettings::IniFormat);
        Settings newSettings;

        if ( Settings::canModifySettings() && newSettings.isEmpty() ) {
            COPYQ_LOG("Migrating configuration to application directory.");
            const QString newConfigPath = QDir::cleanPath(newSettings.fileName() + "/..");

            // Migrate configuration from system directory.
            migrateDirectory(oldConfigPath, newConfigPath);

            // Migrate themes from system directory.
            migrateDirectory(oldConfigPath + "/themes", newConfigPath + "/themes");

            // Migrate rest of the configuration from the system registry.
            migrateConfig(oldSettings, newSettings);
        }
    } else {
        log( QString("Ignoring configuration in \"%1\" (https://github.com/hluk/CopyQ/issues/583).")
             .arg(path), LogWarning );

        QSettings oldSettings;

        QSettings::setDefaultFormat(QSettings::IniFormat);
        Settings newSettings;

        // Move settings from Windows registry.
        if (newSettings.isEmpty()) {
            COPYQ_LOG("Moving configuration from Windows registry.");
            migrateConfig(oldSettings, newSettings);
        }
    }
}
Esempio n. 2
0
    void resetClipboard()
    {
        if (m_resetTimer.isActive() || m_syncTimer.isActive())
            return;

        if (m_resetSelection && !m_selectionData.isEmpty()) {
            COPYQ_LOG( QString("Resetting selection") );
            setClipboardData(m_selectionData, QClipboard::Selection);
        }

        if (m_resetClipboard && !m_clipboardData.isEmpty()) {
            COPYQ_LOG( QString("Resetting clipboard") );
            setClipboardData(m_clipboardData, QClipboard::Clipboard);
        }
    }
Esempio n. 3
0
void ClipboardServer::onSaveState(QSessionManager &sessionManager)
{
    COPYQ_LOG("Got save state request from session manager.");

    QSettings settings(QSettings::IniFormat, QSettings::UserScope, "copyq", "copyq_no_session");
    const auto sessionNameKey = "session_" + sessionManager.sessionId();
    const auto sessionName = qApp->property("CopyQ_session_name").toString();
    settings.setValue(sessionNameKey, sessionName);

    const QString lastSessionIdPrefix = "last_session_id_for_";
    const auto lastSessionIdKey = lastSessionIdPrefix + sessionName;
    const auto lastSessionId = settings.value(lastSessionIdKey).toString();
    const auto lastSessionNameKey = "session_" + lastSessionId;
    settings.setValue(lastSessionIdKey, sessionNameKey);

    // Remove no longer valid sessions from configuration.
    QSet<QString> validSessions;
    for (const QString &key : settings.childKeys()) {
        if ( key.startsWith(lastSessionIdPrefix) )
            validSessions.insert( settings.value(key).toString() );
    }

    for (const QString &key : settings.childKeys()) {
        if ( !key.startsWith(lastSessionIdPrefix) && !validSessions.contains(key) )
            settings.remove(key);
    }
}
Esempio n. 4
0
void ActionHandler::action(Action *action)
{
    action->setParent(this);

    m_lastAction = action;

    connect( action, SIGNAL(newItems(QStringList, QString)),
             this, SLOT(addItems(QStringList, QString)) );
    connect( action, SIGNAL(newItems(QStringList, QModelIndex)),
             this, SLOT(addItems(QStringList, QModelIndex)) );
    connect( action, SIGNAL(newItem(QByteArray, QString, QString)),
             this, SLOT(addItem(QByteArray, QString, QString)) );
    connect( action, SIGNAL(newItem(QByteArray, QString, QModelIndex)),
             this, SLOT(addItem(QByteArray, QString, QModelIndex)) );
    connect( action, SIGNAL(actionStarted(Action*)),
             this, SLOT(actionStarted(Action*)) );
    connect( action, SIGNAL(actionFinished(Action*)),
             this, SLOT(closeAction(Action*)) );
    connect( action, SIGNAL(actionError(Action*)),
             this, SLOT(closeAction(Action*)) );

    ++m_actionCounter;

    if ( !action->outputFormat().isEmpty() && action->outputTab().isEmpty() )
        action->setOutputTab(m_currentTabName);

    m_activeActionDialog->actionAboutToStart(action);
    COPYQ_LOG( QString("Executing: %1").arg(action->command()) );
    action->start();
}
Esempio n. 5
0
QDataStream &operator<<(QDataStream &stream, const ClipboardModel &model)
{
    int length = model.rowCount();
    stream << length;

    COPYQ_LOG( QString("Saving %1 items.").arg(length) );

    // save in reverse order so the items
    // can be later restored in right order
    for(int i = 0; i < length; ++i)
        stream << *model.at(i);

    COPYQ_LOG("Items saved.");

    return stream;
}
Esempio n. 6
0
void migrateConfigToAppDir()
{
    const QString path = QCoreApplication::applicationDirPath() + "/config";
    QDir dir(path);

    if ( (dir.isReadable() || dir.mkdir(".")) && dir.mkpath("copyq") ) {
        QSettings oldSettings;
        const QString oldConfigFileName =
                QSettings(QSettings::IniFormat, QSettings::UserScope,
                          QCoreApplication::organizationName(),
                          QCoreApplication::applicationName()).fileName();
        const QString oldConfigPath = QDir::cleanPath(oldConfigFileName + "/..");

        QSettings::setPath(QSettings::IniFormat, QSettings::UserScope, path);
        QSettings::setDefaultFormat(QSettings::IniFormat);
        Settings newSettings;

        if ( Settings::isEmpty(newSettings) ) {
            COPYQ_LOG("Migrating configuration to application directory.");
            const QString newConfigPath = QDir::cleanPath(newSettings.fileName() + "/..");

            // Migrate configuration from system directory.
            migrateDirectory(oldConfigPath, newConfigPath);

            // Migrate themes from system directory.
            QDir(newConfigPath).mkdir("themes");
            migrateDirectory(oldConfigPath + "/themes", newConfigPath + "/themes");

            // Migrate rest of the configuration from the system registry.
            foreach ( const QString &key, oldSettings.allKeys() )
                newSettings.setValue(key, oldSettings.value(key));
        }
    } else {
Esempio n. 7
0
void ClipboardServer::onClientNewConnection(const ClientSocketPtr &client)
{
    if (m_ignoreNewConnections) {
        COPYQ_LOG("Ignoring new client while exiting");
        client->close();
        return;
    }

    auto proxy = new ScriptableProxy(m_wnd);
    connect( client.get(), &ClientSocket::destroyed,
             proxy, &ScriptableProxy::safeDeleteLater );
    connect( proxy, &ScriptableProxy::sendMessage,
             client.get(), &ClientSocket::sendMessage );

    m_clients.insert( client->id(), ClientData(client, proxy) );
    connect( this, &ClipboardServer::closeClients,
             client.get(), &ClientSocket::close );
    connect( client.get(), &ClientSocket::messageReceived,
             this, &ClipboardServer::onClientMessageReceived );
    connect( client.get(), &ClientSocket::disconnected,
             this, &ClipboardServer::onClientDisconnected );
    connect( client.get(), &ClientSocket::disconnected,
             proxy, &ScriptableProxy::clientDisconnected );
    connect( client.get(), &ClientSocket::connectionFailed,
             this, &ClipboardServer::onClientConnectionFailed );
    client->start();
}
Esempio n. 8
0
ClipboardMonitor::ClipboardMonitor(int &argc, char **argv)
    : QObject()
    , App(new QApplication(argc, argv))
    , m_formats()
    , m_newdata()
#ifdef COPYQ_WS_X11
    , m_copyclip(false)
    , m_checksel(false)
    , m_copysel(false)
#endif
    , m_socket( new QLocalSocket(this) )
    , m_updateTimer( new QTimer(this) )
    , m_needCheckClipboard(false)
#ifdef COPYQ_WS_X11
    , m_needCheckSelection(false)
    , m_x11(new PrivateX11)
#endif
{
    connect( m_socket, SIGNAL(readyRead()),
             this, SLOT(readyRead()), Qt::DirectConnection );
    connect( m_socket, SIGNAL(disconnected()),
             QApplication::instance(), SLOT(quit()) );

    QStringList args = QCoreApplication::instance()->arguments();
    Q_ASSERT(args.size() == 3);

    const QString &serverName = args[2];
    COPYQ_LOG( QString("Connecting to server \"%1\".").arg(serverName) );
    m_socket->connectToServer(serverName);
    if ( !m_socket->waitForConnected(2000) ) {
        log( tr("Cannot connect to server!"), LogError );
        exit(1);
    }
    COPYQ_LOG("Connected to server.");

    m_updateTimer->setSingleShot(true);
    m_updateTimer->setInterval(300);
    connect( m_updateTimer, SIGNAL(timeout()),
             this, SLOT(updateTimeout()));

#ifdef COPYQ_WS_X11
    connect( &m_x11->timer(), SIGNAL(timeout()),
             this, SLOT(updateSelection()) );
    connect( &m_x11->syncTimer(), SIGNAL(timeout()),
             this, SLOT(synchronize()) );
#endif
}
Esempio n. 9
0
void ClipboardServer::callback(const QString &scriptFunction)
{
    waitForCallbackToFinish();
    COPYQ_LOG( QString("Starting callback: %1").arg(scriptFunction) );
    m_callback = new Action();
    m_callback->setCommand(QStringList() << "copyq" << scriptFunction);
    m_wnd->runInternalAction(m_callback);
}
Esempio n. 10
0
void migrateConfigToAppDir()
{
    const QString path = QCoreApplication::applicationDirPath() + "/config";
    QDir dir(path);

    if ( dir.mkpath("copyq") && dir.isReadable() && QFileInfo(path).isWritable() ) {
        QSettings oldSettings;
        const QString oldConfigFileName =
                QSettings(QSettings::IniFormat, QSettings::UserScope,
                          QCoreApplication::organizationName(),
                          QCoreApplication::applicationName()).fileName();
        const QString oldConfigPath = QDir::cleanPath(oldConfigFileName + "/..");

        QSettings::setPath(QSettings::IniFormat, QSettings::UserScope, path);
        QSettings::setDefaultFormat(QSettings::IniFormat);
        Settings newSettings;

        if ( Settings::canModifySettings() && newSettings.isEmpty() ) {
            COPYQ_LOG("Migrating configuration to application directory.");
            const QString newConfigPath = QDir::cleanPath(newSettings.fileName() + "/..");

            // Migrate configuration from system directory.
            migrateDirectory(oldConfigPath, newConfigPath);

            // Migrate themes from system directory.
            migrateDirectory(oldConfigPath + "/themes", newConfigPath + "/themes");

            // Migrate rest of the configuration from the system registry.
            migrateConfig(oldSettings, newSettings);
        }
    } else {
        COPYQ_LOG( QString("Cannot use \"%1\" directory to save user configuration and items.")
                   .arg(path) );

        QSettings oldSettings;

        QSettings::setDefaultFormat(QSettings::IniFormat);
        Settings newSettings;

        // Move settings from Windows registry.
        if (newSettings.isEmpty()) {
            COPYQ_LOG("Moving configuration from Windows registry.");
            migrateConfig(oldSettings, newSettings);
        }
    }
}
Esempio n. 11
0
bool ShortcutDialog::eventFilter(QObject *object, QEvent *event)
{
    if (object != ui->lineEditShortcut)
        return false;

    if (event->type() == QEvent::KeyPress) {
        QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
        COPYQ_LOG(QString("Shortcut key press: %1").arg(keyEvent->key()));

        const int key = createPlatformNativeInterface()->keyCode(*keyEvent);
        Qt::KeyboardModifiers mods = getModifiers(*keyEvent);

        if (mods == Qt::NoModifier) {
            if (key == Qt::Key_Tab)
                return false;

            if (key == Qt::Key_Escape) {
                reject();
                return true;
            }

            if (m_expectModifier)
                return true;
        }

        event->accept();
        processKey(key, mods);

        if ( isNonModifierKey(key) )
            accept();

        return false;
    } else if (event->type() == QEvent::KeyRelease) {
        QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
        COPYQ_LOG(QString("Shortcut key release: %1").arg(keyEvent->key()));

        Qt::KeyboardModifiers mods = getModifiers(*keyEvent);

        processKey(0, mods);

        return true;
    }

    return false;
}
Esempio n. 12
0
void Server::close()
{
    m_server->close();

    COPYQ_LOG( QString("Sockets open: %1").arg(m_socketCount) );
    while (m_socketCount > 0)
        QCoreApplication::processEvents();

    deleteLater();
}
Esempio n. 13
0
void UnixSignalHandler::handleSignal()
{
    m_signalFdNotifier.setEnabled(false);

    char tmp;
    ::read(signalFd[Read], &tmp, sizeof(tmp));

    COPYQ_LOG("Terminating application on signal.");
    QCoreApplication::exit();
}
Esempio n. 14
0
bool ItemEncryptedSaver::saveItems(const QString &, const QAbstractItemModel &model, QIODevice *file)
{
    const auto length = model.rowCount();
    if (length == 0)
        return false; // No need to encode empty tab.

    QByteArray bytes;

    {
        QDataStream stream(&bytes, QIODevice::WriteOnly);
        stream.setVersion(QDataStream::Qt_4_7);

        stream << static_cast<quint64>(length);

        for (int i = 0; i < length && stream.status() == QDataStream::Ok; ++i) {
            QModelIndex index = model.index(i, 0);
            const QVariantMap dataMap = index.data(contentType::data).toMap();
            stream << dataMap;
        }
    }

    bytes = readGpgOutput(QStringList("--encrypt"), bytes);
    if ( bytes.isEmpty() ) {
        emitEncryptFailed();
        COPYQ_LOG("ItemEncrypt ERROR: Failed to read encrypted data");
        return false;
    }

    QDataStream stream(file);
    stream.setVersion(QDataStream::Qt_4_7);
    stream << QString(dataFileHeaderV2);
    stream.writeRawData( bytes.data(), bytes.size() );

    if ( stream.status() != QDataStream::Ok ) {
        emitEncryptFailed();
        COPYQ_LOG("ItemEncrypt ERROR: Failed to write encrypted data");
        return false;
    }

    return true;
}
Esempio n. 15
0
bool ShortcutDialog::eventFilter(QObject *object, QEvent *event)
{
    if (object != ui->lineEditShortcut)
        return QDialog::eventFilter(object, event);

    if (event->type() == QEvent::KeyPress || event->type() == QEvent::KeyRelease) {
        auto keyEvent = static_cast<QKeyEvent*>(event);
        const int key = createPlatformNativeInterface()->keyCode(*keyEvent);
        const int mods = getModifiers(*keyEvent);

        if (mods == Qt::NoModifier) {
            if (key == Qt::Key_Tab)
                return QDialog::eventFilter(object, event);

            if (key == Qt::Key_Escape) {
                reject();
                return true;
            }
        }

        event->accept();

        if (event->type() == QEvent::KeyPress) {
            COPYQ_LOG(QString("Shortcut key press: %1").arg(keyEvent->key()));

            if ( isModifierKey(keyEvent->key()) ) {
                processKey(0, mods);
            } else {
                processKey(key, mods);
                accept();
            }
        } else if (result() != QDialog::Accepted) {
            COPYQ_LOG(QString("Shortcut key release: %1").arg(keyEvent->key()));
            processKey(0, mods);
        }

        return true;
    }

    return QDialog::eventFilter(object, event);
}
Esempio n. 16
0
void ClipboardServer::onAboutToQuit()
{
    COPYQ_LOG("Closing server.");

    m_ignoreNewConnections = true;

    terminateClients(10000);
    m_server->close(); // No new connections can be open.
    terminateClients(5000);

    m_wnd->saveTabs();
}
Esempio n. 17
0
void ClipboardServer::startMonitoring()
{
    if (m_monitor || m_ignoreNewConnections || !m_wnd->isMonitoringEnabled())
        return;

    COPYQ_LOG("Starting monitor");

    m_monitor = new Action();
    m_monitor->setCommand("copyq monitorClipboard");
    connect( m_monitor.data(), &QObject::destroyed,
             this, &ClipboardServer::onMonitorFinished );
    m_wnd->runInternalAction(m_monitor);
}
Esempio n. 18
0
void ShortcutDialog::processKey(int key, int mods)
{
    m_shortcut = QKeySequence(mods | key);

    // WORKAROUND: Qt has convert some keys to upper case which
    //             breaks some shortcuts on some keyboard layouts.
    m_shortcut = QKeySequence(portableShortcutText(m_shortcut));

    const QString shortcut = m_shortcut.toString();
    COPYQ_LOG(QString("Shortcut: %1").arg(shortcut));

    ui->lineEditShortcut->setText(shortcut);
}
Esempio n. 19
0
bool pasteWithCtrlV(PlatformWindow &window)
{
    const QRegExp re( QSettings().value(optionName).toString() );
    if (re.isEmpty())
        return false;

    if (!re.isValid()) {
        log(QString("Invalid regular expression in option \"%1\": %2")
            .arg(optionName, re.errorString()), LogWarning);
        return false;
    }

    const QString windowTitle = window.getTitle();

    if (re.indexIn(windowTitle) == -1) {
        COPYQ_LOG(QString("Paste with standard shortcut to window \"%1\".")
                  .arg(windowTitle));
        return false;
    }

    COPYQ_LOG(QString("Paste with Ctrl+V requested with option \"%1\" for window \"%2\".")
              .arg(optionName, windowTitle));
    return true;
}
Esempio n. 20
0
ClientSocket::ClientSocket(const QString &serverName, QObject *parent)
    : QObject(parent)
    , m_socket(new QLocalSocket)
    , m_socketId(++lastSocketId)
    , m_closed(false)
{
    m_socket->connectToServer(serverName);

    // Try to connect again in case the server just started.
    if ( m_socket->state() == QLocalSocket::UnconnectedState ) {
        COPYQ_LOG("Waiting for server to start");
        SleepTimer t(1000);
        do {
            m_socket->connectToServer(serverName);
        } while ( m_socket->state() == QLocalSocket::UnconnectedState && t.sleep() );
    }
}
Esempio n. 21
0
Qt::KeyboardModifiers ShortcutDialog::getModifiers(const QKeyEvent &event)
{
    int key = event.key();
    Qt::KeyboardModifiers mods = event.modifiers();

    if (key == Qt::Key_Meta || key == Qt::Key_Super_L || key == Qt::Key_Super_R
            || key == Qt::Key_Hyper_L || key == Qt::Key_Hyper_R)
    {
        m_metaPressed = (event.type() == QEvent::KeyPress);
        COPYQ_LOG(QString("Shortcut \"Meta\" key %1.").arg(m_metaPressed ? "pressed" : "released"));
    }
    if (m_metaPressed)
        mods |= Qt::MetaModifier;
    else
        mods &= ~Qt::MetaModifier;

    return mods;
}
Esempio n. 22
0
void ClipboardServer::onSaveState(QSessionManager &sessionManager)
{
    COPYQ_LOG("Got save state request from session manager.");

    QSettings settings(QSettings::IniFormat, QSettings::UserScope, "copyq", "copyq_no_session");
    const auto sessionNameKey = "session_" + sessionManager.sessionId();
    const auto sessionName = qApp->property("CopyQ_session_name").toString();
    settings.setValue(sessionNameKey, sessionName);

    // Remove last session name from configuration.
    const auto lastSessionIdKey = "last_session_id_for_" + sessionName;
    const auto lastSessionId = settings.value(lastSessionIdKey).toString();
    if ( !lastSessionId.isEmpty() ) {
        const auto lastSessionNameKey = "session_" + lastSessionId;
        settings.remove(lastSessionNameKey);
    }
    settings.setValue(lastSessionIdKey, sessionNameKey);
}
Esempio n. 23
0
void ClipboardServer::stopMonitoring()
{
    if (!m_monitor)
        return;

    COPYQ_LOG("Terminating monitor");

    for (auto it = m_clients.constBegin(); it != m_clients.constEnd(); ++it) {
        const auto &clientData = it.value();
        if (!clientData.isValid())
            continue;

        const auto actionId = clientData.proxy->actionId();
        if ( actionId == m_monitor->id() ) {
            clientData.client->sendMessage(QByteArray(), CommandStop);
            break;
        }
    }
}
Esempio n. 24
0
void ClipboardServer::onCommitData(QSessionManager &sessionManager)
{
    COPYQ_LOG("Got commit data request from session manager.");

    const bool cancel = sessionManager.allowsInteraction() && !askToQuit();
    sessionManager.release();

    if (cancel) {
        sessionManager.cancel();
        startMonitoring();
    } else {
        m_wnd->saveTabs();

        // WORKAROUND: This is required to exit application from
        //             installer, otherwise main window is only
        //             minimized after this when tray is disabled.
        m_wnd->hide();
        exit();
    }
}
Esempio n. 25
0
void ShortcutDialog::processKey(int key, Qt::KeyboardModifiers mods)
{
    int keys = 0;
    if ( isNonModifierKey(key) )
        keys = key;

    if (mods & Qt::ControlModifier)
        keys += Qt::CTRL;
    if (mods & Qt::ShiftModifier)
        keys += Qt::SHIFT;
    if (mods & Qt::AltModifier)
        keys += Qt::ALT;
    if (mods & Qt::MetaModifier)
        keys += Qt::META;

    m_shortcut = QKeySequence(keys);
    QString shortcut = m_shortcut.toString(QKeySequence::NativeText);
    COPYQ_LOG(QString("Shortcut: %1").arg(m_shortcut.toString()));

    ui->lineEditShortcut->setText(shortcut);
}
Esempio n. 26
0
bool isAltTabWindow(HWND window)
{
    if (!window || window == GetShellWindow())
        return false;

    HWND root = GetAncestor(window, GA_ROOTOWNER);

    if (getLastVisibleActivePopUpOfWindow(root) != window)
        return false;

    const QString cls = windowClass(window);
	COPYQ_LOG( QString("cls: \"%1\"").arg(cls) );
    return !cls.isEmpty()
            && cls != "Shell_TrayWnd"
            && cls != "Shell_SecondaryTrayWnd"
            && cls != "DV2ControlHost"
            && cls != "MsgrIMEWindowClass"
            && cls != "SysShadow"
            && cls != "Button"
            && !cls.startsWith("WMP9MediaBarFlyout");
}
Esempio n. 27
0
    /**
     * Remember last non-empty clipboard content and reset clipboard after interval if there is no owner.
     *
     * @return return true if clipboard/selection has no owner and will be reset
     */
    bool maybeResetClipboard(QClipboard::Mode mode)
    {
        bool isClip = (mode == QClipboard::Clipboard);
        bool isEmpty = isClip ? m_x11Platform.isClipboardEmpty() : m_x11Platform.isSelectionEmpty();
        QVariantMap &clipData = isClip ? m_clipboardData : m_selectionData;

        // Need reset?
        if ( !isEmpty || clipData.isEmpty() )
            return false;

        COPYQ_LOG( QString("%1 is empty").arg(isClip ? "Clipboard" : "Selection") );
        bool &reset = isClip ? m_resetClipboard : m_resetSelection;
        reset = !m_syncTimer.isActive() || m_syncTo == mode;

        if (reset) {
            m_syncTimer.stop();
            m_resetTimer.start();
        } else if (m_resetTimer.isActive() && !m_resetClipboard && !m_resetSelection) {
            m_resetTimer.stop();
        }

        return true;
    }
Esempio n. 28
0
int ShortcutDialog::getModifiers(const QKeyEvent &event)
{
    int key = event.key();
    const Qt::KeyboardModifiers mods = event.modifiers();
    int result = 0;

    if (key == Qt::Key_Meta || key == Qt::Key_Super_L || key == Qt::Key_Super_R
            || key == Qt::Key_Hyper_L || key == Qt::Key_Hyper_R)
    {
        m_metaPressed = (event.type() == QEvent::KeyPress);
        COPYQ_LOG(QString("Shortcut \"Meta\" key %1.").arg(m_metaPressed ? "pressed" : "released"));
    }

    if (mods & Qt::ShiftModifier)
        result |= Qt::SHIFT;
    if (mods & Qt::ControlModifier)
        result |= Qt::CTRL;
    if (mods & Qt::AltModifier)
        result |= Qt::ALT;
    if (m_metaPressed || mods & Qt::MetaModifier)
        result |= Qt::META;

    return result;
}
Esempio n. 29
0
void ClientSocket::onReadyRead()
{
    if (!m_socket) {
        SOCKET_LOG("Cannot read message from client. Socket is already deleted.");
        return;
    }

    const qint64 available = m_socket->bytesAvailable();
    m_message.append( m_socket->read(available) );

    while ( !m_message.isEmpty() ) {
        if (!m_hasMessageLength) {
            const int preambleSize = headerDataSize() + streamDataSize(m_messageLength);
            if ( m_message.length() < preambleSize )
                break;

            {
                QDataStream stream(m_message);
                stream.setVersion(QDataStream::Qt_5_0);
                quint32 magicNumber;
                quint32 version;
                stream >> magicNumber >> version >> m_messageLength;
                if ( stream.status() != QDataStream::Ok ) {
                    error("Failed to read message length from client!");
                    return;
                }

                if (magicNumber != protocolMagicNumber) {
                    error("Unexpected message magic number from client!");
                    return;
                }

                if (version != protocolVersion) {
                    error("Unexpected message version from client!");
                    return;
                }
            }

            m_message.remove(0, preambleSize);
            m_hasMessageLength = true;

            if (m_messageLength > bigMessageThreshold)
                COPYQ_LOG( QString("Receiving big message: %1 MiB").arg(m_messageLength / 1024 / 1024) );
        }

        const auto length = static_cast<int>(m_messageLength);
        if ( m_message.length() < length )
            break;

        QByteArray msg = m_message.mid(0, length);
        qint32 messageCode;

        if ( !readValue(&messageCode, &msg) ) {
            error("Failed to read message code from client!");
            return;
        }

        m_hasMessageLength = false;
        m_message = m_message.mid(length);

        emit messageReceived(msg, messageCode, id());
    }
}
Esempio n. 30
0
ClipboardServer::ClipboardServer(QApplication *app, const QString &sessionName)
    : QObject()
    , App(app, sessionName)
    , m_wnd(nullptr)
    , m_shortcutActions()
    , m_ignoreKeysTimer()
{
    setCurrentThreadName("Server");

    const QString serverName = clipboardServerName();
    m_server = new Server(serverName, this);

    if ( m_server->isListening() ) {
        ::createSessionMutex();
        restoreSettings(true);
        COPYQ_LOG("Server \"" + serverName + "\" started.");
    } else {
        restoreSettings(false);
        COPYQ_LOG("Server \"" + serverName + "\" already running!");
        log( tr("CopyQ server is already running."), LogWarning );
        exit(0);
        return;
    }

    QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps, true);

    QApplication::setQuitOnLastWindowClosed(false);

    m_itemFactory = new ItemFactory(this);
    m_wnd = new MainWindow(m_itemFactory);

    m_itemFactory->loadPlugins();
    if ( !m_itemFactory->hasLoaders() )
        log("No plugins loaded", LogNote);

    m_wnd->loadSettings();
    m_wnd->setCurrentTab(0);
    m_wnd->enterBrowseMode();

    connect( m_server, &Server::newConnection,
             this, &ClipboardServer::onClientNewConnection );

    connect( qApp, &QCoreApplication::aboutToQuit,
             this, &ClipboardServer::onAboutToQuit );

    connect( qApp, &QGuiApplication::commitDataRequest, this, &ClipboardServer::onCommitData );
    connect( qApp, &QGuiApplication::saveStateRequest, this, &ClipboardServer::onSaveState );
#if QT_VERSION >= QT_VERSION_CHECK(5,6,0)
    qApp->setFallbackSessionManagementEnabled(false);
#endif

    connect( m_wnd, &MainWindow::requestExit,
             this, &ClipboardServer::maybeQuit );
    connect( m_wnd, &MainWindow::disableClipboardStoringRequest,
             this, &ClipboardServer::onDisableClipboardStoringRequest );

    loadSettings();

    // notify window if configuration changes
    connect( m_wnd, &MainWindow::configurationChanged,
             this, &ClipboardServer::loadSettings );

    connect( m_wnd, &MainWindow::commandsSaved,
             this, &ClipboardServer::onCommandsSaved );
    onCommandsSaved();

    qApp->installEventFilter(this);

    m_server->start();

    // Ignore global shortcut key presses in any widget.
    m_ignoreKeysTimer.setInterval(100);
    m_ignoreKeysTimer.setSingleShot(true);

    startMonitoring();
}