bool ItemEditor::start() { // create temp file QTemporaryFile tmpfile; const auto suffix = getFileSuffixFromMime(m_mime); if ( !openTemporaryFile(&tmpfile, suffix) ) { log("Failed to create temporary file for external editor", LogError); return false; } const auto fileName = tmpfile.fileName(); // write text to temp file tmpfile.write(m_data); // Close file before launching editor (this is required on Windows). tmpfile.setAutoRemove(false); tmpfile.close(); // monitor file m_info.setFile(fileName); m_lastmodified = m_info.lastModified(); m_lastSize = m_info.size(); m_timer->start(500); connect( m_timer, &QTimer::timeout, this, &ItemEditor::onTimer ); // create editor process m_editor = new QProcess(this); connectProcessFinished(m_editor, this, &ItemEditor::close); connectProcessError(m_editor, this, &ItemEditor::onError); // use native path for filename to edit const auto nativeFilePath = QDir::toNativeSeparators( m_info.absoluteFilePath() ); const auto cmd = m_editorcmd.arg('"' + nativeFilePath + '"'); // execute editor m_editor->start(cmd, QIODevice::ReadOnly); m_editor->closeWriteChannel(); m_editor->closeReadChannel(QProcess::StandardOutput); return m_editor->waitForStarted(10000); }
void Action::start() { closeSubCommands(); if ( m_currentLine + 1 >= m_cmds.size() ) { finish(); return; } ++m_currentLine; const QList<QStringList> &cmds = m_cmds[m_currentLine]; Q_ASSERT( !cmds.isEmpty() ); QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); if (m_id != -1) env.insert("COPYQ_ACTION_ID", QString::number(m_id)); if ( !m_name.isEmpty() ) env.insert("COPYQ_ACTION_NAME", m_name); for (int i = 0; i < cmds.size(); ++i) { auto process = new QProcess(this); m_processes.push_back(process); process->setProcessEnvironment(env); if ( !m_workingDirectoryPath.isEmpty() ) process->setWorkingDirectory(m_workingDirectoryPath); connectProcessError(process, this, &Action::onSubProcessError); connect( process, &QProcess::readyReadStandardError, this, &Action::onSubProcessErrorOutput ); } pipeThroughProcesses(m_processes.begin(), m_processes.end()); QProcess *lastProcess = m_processes.back(); connect( lastProcess, &QProcess::started, this, &Action::onSubProcessStarted ); connectProcessFinished( lastProcess, this, &Action::onSubProcessFinished ); connect( lastProcess, &QProcess::readyReadStandardOutput, this, &Action::onSubProcessOutput ); // Writing directly to stdin of a process on Windows can hang the app. QProcess *firstProcess = m_processes.front(); connect( firstProcess, &QProcess::started, this, &Action::writeInput, Qt::QueuedConnection ); connect( firstProcess, &QProcess::bytesWritten, this, &Action::onBytesWritten, Qt::QueuedConnection ); const bool needWrite = !m_input.isEmpty(); if (m_processes.size() == 1) { const auto mode = (needWrite && m_readOutput) ? QIODevice::ReadWrite : needWrite ? QIODevice::WriteOnly : m_readOutput ? QIODevice::ReadOnly : QIODevice::NotOpen; startProcess(firstProcess, cmds.first(), mode); } else { auto it = m_processes.begin(); auto cmdIt = cmds.constBegin(); startProcess(*it, *cmdIt, needWrite ? QIODevice::ReadWrite : QIODevice::ReadOnly); for (++it, ++cmdIt; it != m_processes.end() - 1; ++it, ++cmdIt) startProcess(*it, *cmdIt, QIODevice::ReadWrite); startProcess(lastProcess, cmds.last(), m_readOutput ? QIODevice::ReadWrite : QIODevice::WriteOnly); } }