void SocketListener::onNewConnection() {
	JUFFENTRY;
	
	QLocalSocket* socket = server_->nextPendingConnection();
	if ( !socket->waitForReadyRead(1000) ) {
		qDebug() << "Couldn't read data:" << socket->errorString();
		return;
	}
	
	QByteArray data = socket->readAll();
	JUFFDEBUG(QString::fromLocal8Bit(data));
	if ( data.isEmpty() ) {
		return;
	}
	
	QStringList list = QString::fromLocal8Bit(data).split(";");
	foreach (QString arg, list) {
		if ( arg[0] == '-' ) {
			if ( arg.compare("--newfile") == 0 ) {
				emit newFileRequested();
			}
		}
		else {
			if ( !arg.isEmpty() )
				emit fileRecieved(QFileInfo(arg).absoluteFilePath());
		}
	}
}
void ApplicationSingleton::setupPrimary()
{
    m_primaryPid = QCoreApplication::applicationPid();

    qCInfo(log, "Starting as a primary instance. (PID: %lld)", m_primaryPid);

    m_sharedMemory->lock();
    auto sd = static_cast<SharedData *>(m_sharedMemory->data());
    sd->primaryPid = m_primaryPid;
    m_sharedMemory->unlock();

    QLocalServer::removeServer(m_id);

    m_localServer = new QLocalServer(this);
    m_localServer->setSocketOptions(QLocalServer::UserAccessOption);

    connect(m_localServer, &QLocalServer::newConnection, this, [this] {
        QLocalSocket *socket = m_localServer->nextPendingConnection();
        connect(socket, &QLocalSocket::readyRead, this, [this, socket] {
            QByteArray data = socket->readAll();
            emit messageReceived(data);
            socket->deleteLater();
        });
    });

    if (!m_localServer->listen(m_id)) {
        qCWarning(log) << "Cannot start the local service:"
                       << m_localServer->errorString();
        return;
    }
}
void MainWindow::newData()
{
    if(connectedMode=="Tcp socket (QTcpServer)") // if connection is on tcp socket mode
    {
        QTcpSocket *socket = qobject_cast<QTcpSocket *>(sender());
        int index=-1;
        for (int i = 0; i < tcpSocket.size(); ++i) {
            if(tcpSocket.at(i)->tcpSocket==socket)
                index=i;
        }
        if(index==-1)
        {
            ui->statusBarApp->showMessage("Internal error at newData()",10000);
            return;
        }
        QByteArray block=socket->readAll();
        //load in hexa if needed and append or update the text
        if(ui->comboBoxModeAppend->currentText()=="Update")
            tcpSocket[index]->IncomingData.clear();

        QByteArray raw_data;
        if(ui->compressedStream->isChecked())
            raw_data=tcpSocket[index]->compression->decompressData(block);
        else
            raw_data=block;
        //load in hexa if needed and append or update the text
        tcpSocket[index]->IncomingData.append(raw_data);

        updateCurrentData();
    }
    if(connectedMode==COMBOBOXTEXTLOCALSOCK) // if connection is on local socket mode
    {
        QLocalSocket *socket = qobject_cast<QLocalSocket *>(sender());
        int index=-1;
        for (int i = 0; i < localSocket.size(); ++i) {
            if(localSocket.at(i)->localSocket==socket)
                index=i;
        }
        if(index==-1)
        {
            ui->statusBarApp->showMessage("Internal error at newData()",10000);
            return;
        }
        QByteArray block=socket->readAll();
        //load in hexa if needed and append or update the text
        if(ui->comboBoxModeAppend->currentText()=="Update")
            localSocket[index]->IncomingData.clear();

        QByteArray raw_data;
        if(ui->compressedStream->isChecked())
            raw_data=tcpSocket[index]->compression->decompressData(block);
        else
            raw_data=block;

        localSocket[index]->IncomingData.append(raw_data);
        updateCurrentData();
    }
}
Exemple #4
0
void SocketExternalCommunicator::onReadyRead()
{
    QLocalSocket* socket = qobject_cast<QLocalSocket*>(sender());
    QByteArray data;
    data.append(socket->readAll());
    socket->close();

    emit loadFile(QString::fromUtf8(data));
}
Exemple #5
0
/**
 * @brief Executed when the showUp command is sent to LocalServer
 */
void SingleApplication::slotConnectionEstablished()
{
    QLocalSocket *socket = d_ptr->server->nextPendingConnection();

    QByteArray data;
    if (socket->waitForReadyRead())
        data = socket->readAll();

    socket->close();
    delete socket;
    emit otherInstanceDataReceived(data);
}
void CLocalSvrCommunication::GetData( )
{
    QLocalSocket* pSocket = qobject_cast< QLocalSocket* >( sender( ) );

    quint64 nDataSize = pSocket->bytesAvailable( );
    if ( 0 == nDataSize ) {
        return;
    }

    QByteArray byData = pSocket->readAll( );
    QString strMsg( byData );
    emit NotifyMsg( strMsg );
}
Exemple #7
0
void SingleApp::receiveMessage()
{
        QLocalSocket *localSocket = localServer->nextPendingConnection();
        if (!localSocket->waitForReadyRead(timeout))
        {
                qDebug("%s", qPrintable(localSocket->errorString().toLatin1()));
                return;
        }
        QByteArray byteArray = localSocket->readAll();
        QString message = QString::fromUtf8(byteArray.constData());
        emit messageReceived(message);
        localSocket->disconnectFromServer();
}
void mASocketManager::newConnection()
{
    //fprintf(stderr, "[miniAudicle]: received connection from remote\n");
    //fflush(stderr);
    
    QLocalSocket * socket = m_server->nextPendingConnection();
    
    QByteArray data;
    QString path;
    int timeouts = 0;
    
    while(timeouts < MAX_TIMEOUTS)
    {
        if(socket->bytesAvailable() <= 0 && !socket->waitForReadyRead(MAX_TIMEOUT_MS/MAX_TIMEOUTS))
            timeouts++;
        else
        {
            QByteArray bytes = socket->readAll();
            data.append(bytes);
            
            bytes.append('\0');
            //fprintf(stderr, "[miniAudicle]: received data '%s'\n", bytes.constData());
            
            // check for line ending
            if(data.at(data.length()-1) == '\n')
            {
                path = QString(data);
                // remove trailing \n
                path.remove(path.length()-1, 1);
                
                socket->close();
                socket = NULL;
                break;
            }
        }
    }
    
    if(path.length())
    {
        if(QFileInfo(path).exists())
        {
            //fprintf(stderr, "[miniAudicle]: received path '%s' from remote\n", path.toUtf8().constData());
            //fflush(stderr);
            m_mainWindow->openFile(path);
            m_mainWindow->activateWindow();
            m_mainWindow->raise();
            m_mainWindow->show();
        }
    }
}
Exemple #9
0
void Application::receiveMessage()
{
    QLocalSocket *localSocket = d_ptr->localServer.nextPendingConnection();

    if (!localSocket->waitForReadyRead(GUI_APPLICATION_LOCAL_SOCKET_TIMEOUT))
        return;

    QByteArray byteArray = localSocket->readAll();
    const QString message = QString::fromUtf8(byteArray.constData());

    if (message == "raise")
        emit raiseRequested();

    localSocket->disconnectFromServer();
}
Exemple #10
0
void IPC::handleConnection(){
    QLocalSocket *clientConnection = this->m_server->nextPendingConnection();
    connect(clientConnection, &QLocalSocket::disconnected,
            clientConnection, &QLocalSocket::deleteLater);

    clientConnection->waitForReadyRead(2);
    QByteArray cmdArray = clientConnection->readAll();
    QString cmdString = QTextCodec::codecForMib(106)->toUnicode(cmdArray);  // UTF-8
    qDebug() << cmdString;

    this->parseCommand(cmdString);

    clientConnection->close();
    delete clientConnection;
}
//New messages detected
void LSingleApplication::newInputsAvailable(){
  while(lserver->hasPendingConnections()){
    QLocalSocket *sock = lserver->nextPendingConnection();
    QByteArray bytes;
    sock->waitForReadyRead();
    while(sock->bytesAvailable() > 0){ //if(sock->waitForReadyRead()){
	//qDebug() << "Info Available";
	bytes.append( sock->readAll() );
    }
    sock->disconnectFromServer();
    QStringList inputs = QString::fromLocal8Bit(bytes).split("::::");
    //qDebug() << " - New Inputs Detected:" << inputs;
    emit InputsAvailable(inputs);
  }
}
Exemple #12
0
void Listener::readFromSocket()
{
    QLocalSocket *socket = qobject_cast<QLocalSocket *>(sender());
    if (!socket) {
        return;
    }

    log("Reading from socket...");
    for (Client &client: m_connections) {
        if (client.socket == socket) {
            client.commandBuffer += socket->readAll();
            if (processClientBuffer(client) && !m_clientBufferProcessesTimer->isActive()) {
                // we have more client buffers to handle
                m_clientBufferProcessesTimer->start();
            }
            break;
        }
    }
}
void QServer::readSocket()
{
	//Pointer to the signal sender
	QLocalSocket * socket = (QLocalSocket*)sender();

	//Read all data on the socket & store it on a QByteArray
	QByteArray block = socket->readAll();

	//Data stream to easy read all data
	QDataStream in(&block, QIODevice::ReadOnly);
    in.setVersion(QDataStream::Qt_5_4);

	while (!in.atEnd()) //loop needed cause some messages can come on a single packet
	{
		QString receiveString;
		in >> receiveString;
		receiveString.prepend(QString("%1 :: ").arg(socket->socketDescriptor()));
		emit sms(receiveString);
	}	
}
Exemple #14
0
void Listener::readFromSocket()
{
    QLocalSocket *socket = qobject_cast<QLocalSocket *>(sender());
    if (!socket) {
        return;
    }

    Console::main()->log("Reading from socket...");
    for (Client &client: m_connections) {
        if (client.socket == socket) {
            Console::main()->log(QString("    Client: %1").arg(client.name));
            client.commandBuffer += socket->readAll();
            // FIXME: schedule these rather than process them all at once
            //        right now this can lead to starvation of clients due to
            //        one overly active client
            while (processClientBuffer(client)) {}
            break;
        }
    }
}
Exemple #15
0
unsigned int LocalPeer::get_hwnd_and_activate()
{
    unsigned int hwnd = 0;

#ifdef _WIN32
    QLocalSocket socket;
    bool connOk = false;
    int timeout = 5000;

    for(int i = 0; i < 2; i++) 
    {
        socket.connectToServer(socket_name_);
        connOk = socket.waitForConnected(timeout/2);
        if (connOk || i)
            break;
        int ms = 250;
        Sleep(DWORD(ms));
    }

    if (!connOk)
        return false;

    QByteArray uMsg((QString(crossprocess_message_get_hwnd_activate)).toUtf8());
    QDataStream ds(&socket);
    ds.writeBytes(uMsg.constData(), uMsg.size());

    if (socket.waitForBytesWritten(timeout))
    {
        if (socket.waitForReadyRead(timeout))
        {
            QByteArray data_read = socket.readAll();
            if (data_read.size() == sizeof(hwnd))
            {
                hwnd = *(unsigned int*) data_read.data();
            }
        }
    }
#endif _WIN32

    return hwnd;
}
Exemple #16
0
void QtLocalPeer::receiveMessage()
{
    QLocalSocket *socket = (QLocalSocket*)(sender());
    QString msg;

    while (socket->bytesAvailable() > 0) {
        if (socket->canReadLine()) {
            msg = socket->readLine();
        } else {
            msg = socket->readAll();
        }

        // qDebug()<<"local peer reciveing data:"<<msg<<socket->bytesAvailable();
        if (this->isClient()) {
            emit messageReceived(msg);
        } else {
            int client_id = this->clients.value(socket);
            emit messageReceived(msg, client_id);        
        }
    }
}
Exemple #17
0
void Connection::getInitialData()
{
    mInitialDataReceived = false;

    // blockingly handle all remote calls until the simulator signals the initial data
    // sending is done
    QByteArray readBuffer;
    QLocalSocket *readSocket = mConnection->receiveSocket();
    while (!mInitialDataReceived) {
        readSocket->waitForReadyRead(100);
        readBuffer += readSocket->readAll();
        forever {
            IncomingRemoteMetacall rpc;
            if (rpc.read(&readBuffer)) {
                if (rpc.call(readSocket, this))
                    continue;
                qWarning("Ignoring a call to %s,", rpc.signature().data());
            }
            break;
        }
    }
}
Exemple #18
0
int main(int argv, char** args) {
  QApplication app(argv, args);

  QLocalSocket sock;
  QObject::connect(&sock, &QLocalSocket::readyRead, [&sock]() {
    qint64 bytesAvailable = sock.bytesAvailable();
    QByteArray buffer = sock.readAll();
    QDataStream ds(buffer);
    while (bytesAvailable > 0) {
      int num;
      ds >> num;

      qDebug("received %d", num);
      bytesAvailable -= 4;

      if (num == 1) {
        sendData(sock, 2);
        sendData(sock, -1);
      } else if (num == 3) {
        sendData(sock, -3);
      }
    }
  });
Exemple #19
0
static bool sendData(const QByteArray &out, QByteArray *in)
{
#if USE_LOCAL_SOCKETS
    QLocalSocket socket;
    socket.connectToServer("gdrdeamon");
#else
    QTcpSocket socket;
    socket.connectToHost("127.0.0.1", 15001);
#endif
    if (!socket.waitForConnected(1000))
        return false;

    qint32 size = out.size();
    socket.write((char*)&size, sizeof(qint32));
    socket.write(out);
    while (socket.bytesToWrite() && socket.waitForBytesWritten())
        ;

    while (socket.waitForReadyRead())
        in->append(socket.readAll());

    return true;
}
Exemple #20
0
void DaoxDebugger::slotSetBreakPoint()
{
	QLocalSocket *socket = server.nextPendingConnection();
	QByteArray sdata;
	QTime dieTime= QTime::currentTime().addMSecs(1000);
	while( socket->isValid() && sdata.count( '\0' ) < 2 ){
		if( QTime::currentTime() > dieTime ) break;
		socket->waitForReadyRead();
		sdata += socket->readAll();
	}
	QList<QByteArray> data = sdata.split( '\0' );
	if( data.size() < 3 ) return;

	QString name = data[0];
	int set = data[1].toInt();
	int line = data[2].toInt();
	if( set ){
		if( not breakPoints.contains( name ) ) breakPoints[ name ] = QMap<int,int>();
		breakPoints[ name ][ line ] = 1;
	}else{
		if( breakPoints.contains( name ) ) breakPoints[name].remove( line );
		if( breakPoints[name].size() ==0 ) breakPoints.remove( name );
	}
}
RunControl *WinRtDebugSupport::createDebugRunControl(WinRtRunConfiguration *runConfig,
                                                     Core::Id mode,
                                                     QString *errorMessage)
{
    // FIXME: This is just working for local debugging;
    using namespace Debugger;
    DebuggerStartParameters params;
    params.startMode = AttachExternal;
    // The first Thread needs to be resumed manually.
    params.commandsAfterConnect = "~0 m";

    QFileInfo debuggerHelper(QCoreApplication::applicationDirPath()
                             + QLatin1String("/winrtdebughelper.exe"));
    if (!debuggerHelper.isExecutable()) {
        *errorMessage = tr("The WinRT debugging helper is missing from your Qt Creator "
                           "installation. It was assumed to be located at %1").arg(
                    debuggerHelper.absoluteFilePath());
        return 0;
    }

    if (useQmlDebugging(runConfig)) {
        quint16 qmlDebugPort = 0;
        if (!getFreePort(qmlDebugPort, errorMessage))
            return 0;
        runConfig->setArguments(runConfig->arguments() + QLatin1Char(' ')
                    + QmlDebug::qmlDebugTcpArguments(QmlDebug::QmlDebuggerServices, qmlDebugPort));
        params.qmlServerAddress = QHostAddress::LocalHost;
        params.qmlServerPort = qmlDebugPort;
    }

    WinRtRunnerHelper *runner = new WinRtRunnerHelper(runConfig, errorMessage);
    if (!errorMessage->isEmpty())
        return 0;

    QLocalServer server;
    server.listen(QLatin1String("QtCreatorWinRtDebugPIDPipe"));

    runner->debug(debuggerHelper.absoluteFilePath());
    if (!runner->waitForStarted()) {
        *errorMessage = tr("Cannot start the WinRT Runner Tool.");
        return 0;
    }

    if (!server.waitForNewConnection(10000)) {
        *errorMessage = tr("Cannot establish connection to the WinRT debugging helper.");
        return 0;
    }

    while (server.hasPendingConnections()) {
        QLocalSocket *connection = server.nextPendingConnection();
        if (connection->waitForReadyRead(1000)) {
            const QByteArray &output = connection->readAll();
            QList<QByteArray> arg = output.split(':');
            if (arg.first() == "PID") {
                bool ok =false;
                params.attachPID = arg.last().toInt(&ok);
                if (!ok) {
                    *errorMessage = tr("Cannot extract the PID from the WinRT debugging helper. "
                                       "(output: %1)").arg(QString::fromLocal8Bit(output));
                    return 0;
                }
                server.close();
                Debugger::DebuggerRunControl *debugRunControl
                        = createDebuggerRunControl(params, runConfig, errorMessage, mode);
                runner->setDebugRunControl(debugRunControl);
                new WinRtDebugSupport(debugRunControl, runner);
                return debugRunControl;
            }
        }
    }

    server.close();

    *errorMessage = tr("Cannot create an appropriate run control for "
                       "the current run configuration.");

    return 0;
}
RunControl *WinRtDebugSupport::createDebugRunControl(WinRtRunConfiguration *runConfig,
                                                     RunMode mode,
                                                     QString *errorMessage)
{
    // FIXME: This is just working for local debugging;
    using namespace Debugger;
    DebuggerStartParameters params;
    params.startMode = AttachExternal;
    params.languages |= CppLanguage;
    params.breakOnMain = mode == DebugRunModeWithBreakOnMain;
    // The first Thread needs to be resumed manually.
    params.commandsAfterConnect = "~0 m";
    Kit *kit = runConfig->target()->kit();
    params.debuggerCommand = DebuggerKitInformation::debuggerCommand(kit).toString();
    if (ToolChain *tc = ToolChainKitInformation::toolChain(kit))
        params.toolChainAbi = tc->targetAbi();

    QFileInfo debuggerHelper(QCoreApplication::applicationDirPath()
                             + QLatin1String("/winrtdebughelper.exe"));
    if (!debuggerHelper.isExecutable()) {
        *errorMessage = tr("The WinRT debugging helper is missing from your Qt Creator "
                           "installation. It was assumed to be located at %1").arg(
                    debuggerHelper.absoluteFilePath());
        return 0;
    }

    WinRtRunnerHelper *runner = new WinRtRunnerHelper(runConfig, errorMessage);
    if (!errorMessage->isEmpty())
        return 0;

    QLocalServer server;
    server.listen(QLatin1String("QtCreatorWinRtDebugPIDPipe"));

    runner->debug(debuggerHelper.absoluteFilePath());
    if (!runner->waitForStarted()) {
        *errorMessage = tr("Cannot start the WinRT Runner Tool.");
        return 0;
    }

    if (!server.waitForNewConnection(10000)) {
        *errorMessage = tr("Cannot establish connection to the WinRT debugging helper.");
        return 0;
    }

    while (server.hasPendingConnections()) {
        QLocalSocket *connection = server.nextPendingConnection();
        if (connection->waitForReadyRead(1000)) {
            const QByteArray &output = connection->readAll();
            QList<QByteArray> arg = output.split(':');
            if (arg.first() == "PID") {
                bool ok =false;
                params.attachPID = arg.last().toInt(&ok);
                if (!ok) {
                    *errorMessage = tr("Cannot extract the PID from the WinRT debugging helper. "
                                       "(output: %1)").arg(QString::fromLocal8Bit(output));
                    return 0;
                }
                server.close();
                params.runConfiguration = runConfig;
                Debugger::DebuggerRunControl *debugRunControl
                        = createDebuggerRunControl(params, errorMessage);
                runner->setRunControl(debugRunControl);
                new WinRtDebugSupport(debugRunControl, runner);
                return debugRunControl;
            }
        }
    }

    server.close();

    *errorMessage = tr("Cannot create an appropriate run control for "
                       "the current run configuration.");

    return 0;
}
Exemple #23
0
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow),
    settings("Zeal", "Zeal"),
    settingsDialog(zealList)
{
    trayIcon = nullptr;
    trayIconMenu = nullptr;

    // Use the platform-specific proxy settings
    QNetworkProxyFactory::setUseSystemConfiguration(true);

    // server for detecting already running instances
    localServer = new QLocalServer(this);
    connect(localServer, &QLocalServer::newConnection, [&]() {
        QLocalSocket *connection = localServer->nextPendingConnection();
        // Wait a little while the other side writes the bytes
        connection->waitForReadyRead();
        QString indata = connection->readAll();
        if(!indata.isEmpty()) {
            bringToFrontAndSearch(indata);
        }
    });
    QLocalServer::removeServer(serverName);  // remove in case previous instance crashed
    localServer->listen(serverName);

    // initialise icons
#if defined(WIN32) || defined(OSX)
    icon = qApp->style()->standardIcon(QStyle::SP_MessageBoxInformation);
#else
    icon = QIcon::fromTheme("edit-find");
#endif
    setWindowIcon(icon);
    if(settings.value("hidingBehavior", "systray").toString() == "systray")
        createTrayIcon();

    QKeySequence keySequence;
    if(settings.value("hotkey").isNull()) {
        keySequence = QKeySequence("Alt+Space");
    } else {
        keySequence = settings.value("hotkey").value<QKeySequence>();
    }

    // initialise key grabber
    connect(&nativeFilter, &ZealNativeEventFilter::gotHotKey, [&]() {
        if(!isVisible() || !isActiveWindow()) {
            bringToFront(true);
        } else {
            if(trayIcon) {
                hide();
            } else {
                showMinimized();
            }
        }
    });
    qApp->eventDispatcher()->installNativeEventFilter(&nativeFilter);
    setHotKey(keySequence);

    // initialise docsets
    docsets->initialiseDocsets();

    // initialise ui
    ui->setupUi(this);

    setupShortcuts();

    restoreGeometry(settings.value("geometry").toByteArray());
    ui->splitter->restoreState(settings.value("splitter").toByteArray());
    connect(ui->splitter, &QSplitter::splitterMoved, [=](int, int) {
        settings.setValue("splitter", ui->splitter->saveState());
    });
    ui->webView->settings()->setFontSize(QWebSettings::MinimumFontSize, settings.value("minFontSize").toInt());
    ZealNetworkAccessManager * zealNaManager = new ZealNetworkAccessManager();
    ui->webView->page()->setNetworkAccessManager(zealNaManager);

    // menu
    ui->action_Quit->setShortcut(QKeySequence::Quit);
    connect(ui->action_Quit, &QAction::triggered, [=]() { settings.setValue("geometry", saveGeometry()); });
    connect(ui->action_Quit, SIGNAL(triggered()), qApp, SLOT(quit()));

    connect(&settingsDialog, SIGNAL(refreshRequested()), this, SLOT(refreshRequest()));
    connect(&settingsDialog, SIGNAL(minFontSizeChanged(int)), this, SLOT(changeMinFontSize(int)));

    connect(ui->action_Options, &QAction::triggered, [=]() {
        settingsDialog.setHotKey(hotKey);
        nativeFilter.setEnabled(false);
        if(settingsDialog.exec()) {
            setHotKey(settingsDialog.hotKey());
            if(settings.value("hidingBehavior").toString() == "systray") {
                createTrayIcon();
            } else if(trayIcon) {
                trayIcon->deleteLater();
                trayIconMenu->deleteLater();
                trayIcon = nullptr;
                trayIconMenu = nullptr;
            }
        } else {
            // cancelled - restore previous value
            ui->webView->settings()->setFontSize(QWebSettings::MinimumFontSize, settings.value("minFontSize").toInt());
        }
        nativeFilter.setEnabled(true);
        ui->treeView->reset();
    });

    ui->action_Back->setShortcut(QKeySequence::Back);
    ui->action_Forward->setShortcut(QKeySequence::Forward);
    connect(ui->action_Back, &QAction::triggered, this, &MainWindow::back);
    connect(ui->action_Forward, &QAction::triggered, this, &MainWindow::forward);

    connect(ui->action_About, &QAction::triggered,
            [&]() { QMessageBox::about(this, "About Zeal",
                QString("This is Zeal ") + ZEAL_VERSION + " - a documentation browser.\n\n"
                "For details see http://zealdocs.org/"); });
    connect(ui->action_About_QT, &QAction::triggered,
            [&]() { QMessageBox::aboutQt(this); });
    displayViewActions();

    // treeView and lineEdit
    ui->lineEdit->setTreeView(ui->treeView);
    ui->lineEdit->setFocus();
    ui->treeView->setModel(&zealList);
    ui->treeView->setColumnHidden(1, true);
    ui->treeView->setItemDelegate(new ZealSearchItemDelegate(ui->treeView, ui->lineEdit, ui->treeView));
#if QT_VERSION < QT_VERSION_CHECK(5, 1, 0) && defined(WIN32)
    // overriding subElementRect doesn't work with Qt 5.0.0, but is required to display
    // selected item frame correctly in Windows (for patch see https://codereview.qt-project.org/#change,46559)
    // This is a workaround for Qt < 5.1 - selecting whole rows leads to always rendering the frame.
    // (Only the frame is larger than the list item, which is different from default behaviour.)
    ui->treeView->setSelectionBehavior(QAbstractItemView::SelectRows);
#endif
    connect(ui->treeView, &QTreeView::clicked, [&](const QModelIndex& index) {
       ui->treeView->activated(index);
    });
    connect(ui->treeView, &QTreeView::activated, [&](const QModelIndex& index) {
        if(!index.sibling(index.row(), 1).data().isNull()) {
            QStringList url_l = index.sibling(index.row(), 1).data().toString().split('#');
            QUrl url = QUrl::fromLocalFile(url_l[0]);
            if(url_l.count() > 1) {
                url.setFragment(url_l[1]);
            }
            ui->webView->load(url);
        }
    });
    connect(ui->forwardButton, &QPushButton::clicked, this, &MainWindow::forward);
    connect(ui->backButton, &QPushButton::clicked, this, &MainWindow::back);

    connect(ui->webView, &SearchableWebView::urlChanged, [&](const QUrl &url) {
        QString urlPath = url.path();
        QString docsetName = getDocsetName(urlPath);
        QPixmap docsetMap = docsets->icon(docsetName).pixmap(32,32);

        // paint label with the icon
        ui->pageIcon->setPixmap(docsetMap);
        displayViewActions();
    });

    connect(ui->webView, &SearchableWebView::titleChanged, [&](const QString &title) {
        if (!title.isEmpty()) {
            ui->pageTitle->setText(title);
        }
    });

    connect(&zealSearch, &ZealSearchModel::queryCompleted, [&]() {
        ui->treeView->setModel(&zealSearch);
        ui->treeView->reset();
        ui->treeView->setColumnHidden(1, true);
        ui->treeView->setCurrentIndex(zealSearch.index(0, 0, QModelIndex()));
        ui->treeView->activated(ui->treeView->currentIndex());
    });
    connect(ui->lineEdit, &QLineEdit::textChanged, [&](const QString& text) {
        zealSearch.setQuery(text);
        if(text.isEmpty()) {
            ui->treeView->setModel(&zealList);
        }
    });
}
Exemple #24
0
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow),
    m_settings(new QSettings(this)),
    m_zealListModel(new ListModel(this)),
    m_settingsDialog(new SettingsDialog(m_zealListModel, this)),
    m_globalShortcut(new QxtGlobalShortcut(this))
{
    // server for detecting already running instances
    m_localServer = new QLocalServer(this);
    connect(m_localServer, &QLocalServer::newConnection, [&]() {
        QLocalSocket *connection = m_localServer->nextPendingConnection();
        // Wait a little while the other side writes the bytes
        connection->waitForReadyRead();
        QString indata = connection->readAll();
        if (!indata.isEmpty())
            bringToFrontAndSearch(indata);
    });
    QLocalServer::removeServer(serverName);  // remove in case previous instance crashed
    m_localServer->listen(serverName);

    setWindowIcon(QIcon::fromTheme(QStringLiteral("zeal"), QIcon(QStringLiteral(":/zeal.ico"))));

    if (m_settings->value("hidingBehavior", "systray").toString() == "systray")
        createTrayIcon();

    QKeySequence keySequence
            = m_settings->value(QStringLiteral("hotkey"), QStringLiteral("Alt+Space")).value<QKeySequence>();

    // initialise key grabber
    connect(m_globalShortcut, &QxtGlobalShortcut::activated, [&]() {
        if (!isVisible() || !isActiveWindow()) {
            bringToFront(true);
        } else {
#ifdef USE_LIBAPPINDICATOR
            if (m_trayIcon || m_indicator) {
#else
            if (m_trayIcon) {
#endif
                hide();
            } else {
                showMinimized();
            }
        }
    });

    setHotKey(keySequence);

    // initialise docsets
    DocsetsRegistry::instance()->initialiseDocsets();

    // initialise ui
    ui->setupUi(this);

    setupShortcuts();

    restoreGeometry(m_settings->value("geometry").toByteArray());
    ui->splitter->restoreState(m_settings->value("splitter").toByteArray());
    connect(ui->splitter, &QSplitter::splitterMoved, [=](int, int) {
        m_settings->setValue("splitter", ui->splitter->saveState());
    });

    applyWebPageStyle();
    m_zealNetworkManager = new NetworkAccessManager();
    m_zealNetworkManager->setProxy(m_settingsDialog->httpProxy());
#ifdef USE_WEBENGINE
    // FIXME AngularJS workaround (zealnetworkaccessmanager.cpp)
#else
    ui->webView->page()->setNetworkAccessManager(m_zealNetworkManager);
#endif

    // menu
    if (QKeySequence(QKeySequence::Quit) != QKeySequence("Ctrl+Q")) {
        ui->action_Quit->setShortcuts(QList<QKeySequence>{QKeySequence(
                                                              "Ctrl+Q"), QKeySequence::Quit});
    } else {
        // Quit == Ctrl+Q - don't set the same sequence twice because it causes
        // "QAction::eventFilter: Ambiguous shortcut overload: Ctrl+Q"
        ui->action_Quit->setShortcuts(QList<QKeySequence>{QKeySequence::Quit});
    }
    addAction(ui->action_Quit);
    connect(ui->action_Quit, &QAction::triggered, [=]() {
        m_settings->setValue("geometry", saveGeometry());
    });
    connect(ui->action_Quit, SIGNAL(triggered()), qApp, SLOT(quit()));

    connect(m_settingsDialog, SIGNAL(refreshRequested()), this, SLOT(refreshRequest()));
    connect(m_settingsDialog, SIGNAL(minFontSizeChanged(int)), this, SLOT(changeMinFontSize(int)));
    connect(m_settingsDialog, SIGNAL(webPageStyleUpdated()), this, SLOT(applyWebPageStyle()));

    connect(ui->action_Options, &QAction::triggered, [=]() {
        m_settingsDialog->setHotKey(m_globalShortcut->shortcut());

        if (m_settingsDialog->exec()) {
            setHotKey(m_settingsDialog->hotKey());
            if (m_settings->value("hidingBehavior").toString() == "systray") {
                createTrayIcon();
            } else if (m_trayIcon) {
                QMenu *trayIconMenu = m_trayIcon->contextMenu();
                delete m_trayIcon;
                m_trayIcon = nullptr;
                delete trayIconMenu;
            }
        } else {
            // cancelled - restore previous value
            ui->webView->settings()->setFontSize(QWebSettings::MinimumFontSize,
                                                 m_settings->value("minFontSize").toInt());
        }

        ui->treeView->reset();
    });

    ui->action_Back->setShortcut(QKeySequence::Back);
    addAction(ui->action_Back);
    ui->action_Forward->setShortcut(QKeySequence::Forward);
    addAction(ui->action_Forward);
    connect(ui->action_Back, &QAction::triggered, this, &MainWindow::back);
    connect(ui->action_Forward, &QAction::triggered, this, &MainWindow::forward);

    connect(ui->action_About, &QAction::triggered, [&]() {
        QMessageBox::about(this, "About Zeal",
                           QString("This is Zeal ") + ZEAL_VERSION
                           + " - a documentation browser.\n\n"
                           + "For details see http://zealdocs.org/");
    });
    connect(ui->action_About_QT, &QAction::triggered, [&]() {
        QMessageBox::aboutQt(this);
    });

    m_backMenu = new QMenu(ui->backButton);
    ui->backButton->setMenu(m_backMenu);

    m_forwardMenu = new QMenu(ui->forwardButton);
    ui->forwardButton->setMenu(m_forwardMenu);

    displayViewActions();

    // treeView and lineEdit
    ui->lineEdit->setTreeView(ui->treeView);
    ui->lineEdit->setFocus();
    setupSearchBoxCompletions();
    ui->treeView->setModel(m_zealListModel);
    ui->treeView->setColumnHidden(1, true);
    ui->treeView->setItemDelegate(new ZealSearchItemDelegate(ui->treeView, ui->lineEdit,
                                                             ui->treeView));
    m_treeViewClicked = false;

    createTab();

    connect(ui->treeView, &QTreeView::clicked, [&](const QModelIndex &index) {
        m_treeViewClicked = true;
        ui->treeView->activated(index);
    });
    connect(ui->sections, &QListView::clicked, [&](const QModelIndex &index) {
        m_treeViewClicked = true;
        ui->sections->activated(index);
    });
    connect(ui->treeView, &QTreeView::activated, this, &MainWindow::openDocset);
    connect(ui->sections, &QListView::activated, this, &MainWindow::openDocset);
    connect(ui->forwardButton, &QPushButton::clicked, this, &MainWindow::forward);
    connect(ui->backButton, &QPushButton::clicked, this, &MainWindow::back);

    connect(ui->webView, &SearchableWebView::urlChanged, [&](const QUrl &url) {
        const QString name = docsetName(url);
        if (DocsetsRegistry::instance()->names().contains(name))
            loadSections(name, url);

        m_tabBar.setTabIcon(m_tabBar.currentIndex(), docsetIcon(name));
        displayViewActions();
    });

    connect(ui->webView, &SearchableWebView::titleChanged, [&](const QString &) {
        displayViewActions();
    });

    connect(ui->webView, &SearchableWebView::linkClicked, [&](const QUrl &url) {
        QMessageBox question;
        QString messageFormat = QString("Do you want to go to an external link?\nUrl: %1");
        question.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
        question.setText(messageFormat.arg(url.toString()));
        if (question.exec() == QMessageBox::Yes)
            QDesktopServices::openUrl(url);
    });

    ui->sections->hide();
    ui->sections_lab->hide();
    ui->sections->setModel(&m_searchState->sectionsList);
    connect(DocsetsRegistry::instance(), &DocsetsRegistry::queryCompleted, this, &MainWindow::onSearchComplete);
    connect(ui->lineEdit, &QLineEdit::textChanged, [&](const QString &text) {
        if (text == m_searchState->searchQuery)
            return;

        m_searchState->searchQuery = text;
        m_searchState->zealSearch.setQuery(text);
        if (text.isEmpty())
            ui->treeView->setModel(m_zealListModel);
    });

    ui->action_NewTab->setShortcut(QKeySequence::AddTab);
    addAction(ui->action_NewTab);
    connect(ui->action_NewTab, &QAction::triggered, [&]() {
        saveTabState();
        createTab();
    });

    // save the expanded items:
    connect(ui->treeView, &QTreeView::expanded, [&](QModelIndex index) {
        if (m_searchState->expansions.indexOf(index) == -1)
            m_searchState->expansions.append(index);
    });

    connect(ui->treeView, &QTreeView::collapsed, [&](QModelIndex index) {
        m_searchState->expansions.removeOne(index);
    });

#ifdef Q_OS_WIN32
    ui->action_CloseTab->setShortcut(QKeySequence(Qt::Key_W + Qt::CTRL));
#else
    ui->action_CloseTab->setShortcut(QKeySequence::Close);
#endif
    addAction(ui->action_CloseTab);
    connect(ui->action_CloseTab, &QAction::triggered, [&]() {
        closeTab();
    });

    m_tabBar.setTabsClosable(true);
    m_tabBar.setExpanding(false);
    m_tabBar.setUsesScrollButtons(true);
    m_tabBar.setDrawBase(false);

    connect(&m_tabBar, &QTabBar::tabCloseRequested, this, &MainWindow::closeTab);
    ((QHBoxLayout *)ui->frame_2->layout())->insertWidget(2, &m_tabBar, 0, Qt::AlignBottom);

    connect(&m_tabBar, &QTabBar::currentChanged, this, &MainWindow::goToTab);

    connect(ui->openUrlButton, &QPushButton::clicked, [&]() {
        QUrl url(ui->webView->page()->history()->currentItem().url());
        if (url.scheme() != "qrc")
            QDesktopServices::openUrl(url);
    });

    ui->action_NextTab->setShortcut(QKeySequence::NextChild);
    addAction(ui->action_NextTab);
    connect(ui->action_NextTab, &QAction::triggered, [&]() {
        m_tabBar.setCurrentIndex((m_tabBar.currentIndex() + 1) % m_tabBar.count());
    });

    ui->action_PreviousTab->setShortcut(QKeySequence::PreviousChild);
    addAction(ui->action_PreviousTab);
    connect(ui->action_PreviousTab, &QAction::triggered, [&]() {
        m_tabBar.setCurrentIndex((m_tabBar.currentIndex() - 1 + m_tabBar.count()) % m_tabBar.count());
    });
}
/**
 * @brief read data from plugin. Divide it on packets and handle packets by its type.
 */
void ExternalPluginServer::readPluginData()
{
    QLocalSocket *connection = qobject_cast<QLocalSocket *>(QObject::sender());
    if (connection == 0) {
        qWarning() << "Unknown type of sender";
        return;
    }
    QByteArray data = connection->readAll();
    QList<QByteArray> packets;

    //  Divide readed data on packets by separator - PLUGIN_PACKET_PREAMBLE
    int receivedBytes = data.size();
    int pos = data.indexOf(PLUGIN_PACKET_PREAMBLE);
    while (pos >= 0) {
        if ((receivedBytes - pos) < (int)PLUGIN_PACKET_LENGTH) {
            qWarning() << "Some data from plugin is missed. Received:" << receivedBytes;
            qCritical() << "Recieved from plugin:" << data;
            Q_ASSERT(false);
            break;
        }
        QByteArray packet;
        packet = data.mid(pos, (int)PLUGIN_PACKET_LENGTH);
        packets.append(packet);
        pos = data.indexOf(PLUGIN_PACKET_PREAMBLE, pos + (int)PLUGIN_PACKET_LENGTH);
    }

    //  Handle plugin data
    foreach (QByteArray packet, packets) {
        if (packet.size() != (int)PLUGIN_PACKET_LENGTH) {
            qCritical() << "Incorrect packet size:" << packet.size();
            qCritical() << "Recieved from plugin:" << data;
            Q_ASSERT(false);
            continue;
        }

        pluginPacket_s *data = (pluginPacket_s *)packet.data();
        qDebug() << "UID:" << data->uid << "Events:" << data->eventsCount;
        QString uid = QString("%1").arg(data->uid);

        //  Verify and bind unique connection. Then send events notification to PluginManager
        if (m_pluginConnections.contains(uid)) {
            if (m_pluginConnections.value(uid) != connection) {
                qCritical() << "Simultaneous access from different plugins by same UID:" << uid;
                continue;
            }
            emit eventsGot(data->uid, data->eventsCount);
        } else {
            QList<QLocalSocket *> unbindedConnections = m_pluginConnections.values("-1");
            if (unbindedConnections.contains(connection)) {
                m_pluginConnections.remove("-1", connection);
                if (m_pluginConnections.contains(uid)) {
                    qCritical() << "Plugins with same UID:" << uid << "has been already exist";
                    continue;
                }
                qDebug() << "Bind plugin with UID:" << uid;
                m_pluginConnections.insert(uid, connection);
                emit eventsGot(data->uid, data->eventsCount);
            } else {
                qCritical() << "Recieved data from plugin, which doesn't register in unbinded connections. UID:" << uid;
                continue;
            }
        }
    }
}