From: hama Date: Mon, 25 May 2015 09:53:13 +0000 (+0200) Subject: ReFind: context menu "copy to clipboard" works X-Git-Url: https://gitweb.hamatoma.de/?a=commitdiff_plain;h=5f46e4c3c560fee55b4465c8fab58ce878f81a71;p=reqt ReFind: context menu "copy to clipboard" works --- diff --git a/appl/refind/mainwindow.cpp b/appl/refind/mainwindow.cpp index 2a98cc0..c132247 100644 --- a/appl/refind/mainwindow.cpp +++ b/appl/refind/mainwindow.cpp @@ -344,6 +344,54 @@ void MainWindow::exportToStream(QTextStream& stream, int maxRow){ } } +/** + * Processes the dragging operation of the selected files in the table widget. + */ +void MainWindow::fileDragging(){ + + QDrag *drag = new QDrag(this); + QMimeData *mimeData = new QMimeData; + QList < QUrl > urls; + QList < QTableWidgetSelectionRange > ranges = + ui->tableWidget->selectedRanges(); + QList ::iterator it; + int files = 0; + int dirs = 0; + bool isDir = false; + for (it = ranges.begin(); it != ranges.end(); ++it){ + for (int row = (*it).topRow(); row <= (*it).bottomRow(); row++){ + isDir = cellAsText(row, TC_SIZE).isEmpty(); + QUrl url(buildAbsPath(row, true)); + urls.append(url); + if (isDir) + dirs++; + else + files++; + } + } + if (urls.size() > 0){ + mimeData->setUrls(urls); + drag->setMimeData(mimeData); + QPixmap image(200, 30); + QPainter painter(&image); + QString msg; + if (urls.size() == 1) + msg = tr("copy ") + ReQStringUtil::nodeOf(urls.at(0).toString()); + else if (files > 0 && dirs > 0) + msg = tr("copy %1 file(s) and %2 dir(s)").arg(files).arg(dirs); + else if (files > 0) + msg = tr("copy %1 file(s)").arg(files); + else + msg = tr("copy %1 dirs(s)").arg(dirs); + + painter.fillRect(image.rect(), Qt::white); + painter.drawText(10, 20, msg); + drag->setPixmap(image); + + Qt::DropAction dropAction = drag->exec(Qt::CopyAction); + } +} + /** * Handles the push of "select file placeholder". */ @@ -376,6 +424,90 @@ void MainWindow::fullNameToClipboard(){ } } +/** + * Handle the "copy to clipboard" entry from the context menu. + * + * @param currentRow the row where the context menu is called + * @param full the full name of the current row + */ +void MainWindow::handleCopyToClipboard(int currentRow, const QString& full){ + QMimeData *mimeData = new QMimeData; + QList < QUrl > urls; + bool isInSelection = false; + QList < QTableWidgetSelectionRange > ranges = + ui->tableWidget->selectedRanges(); + QList ::iterator it; + QString textList; + textList.reserve(ui->tableWidget->rowCount() * 80); + for (it = ranges.begin(); it != ranges.end(); ++it){ + for (int row = (*it).topRow(); row <= (*it).bottomRow(); row++){ + isInSelection = isInSelection || row == currentRow; + QString name(buildAbsPath(row, true)); + QUrl url(name); + textList += name + '\n'; + urls.append(url); + } + } + if (!isInSelection){ + urls.clear(); + urls.append(QUrl(full)); + textList = full; + } + mimeData->setUrls(urls); + mimeData->setText(textList); + QClipboard *clipboard = QApplication::clipboard(); + clipboard->setMimeData(mimeData); + setStatusMessage(false, + tr("%1 entry/entries copied to clipboard").arg(urls.length())); +} + +/** + * Starts an external command given by the context menu for the selected file. + * + * @param handler the info about the external program_invocation_short_name + * @param parent the path of the file + * @param full the full file name + * @param node the file name without path + */ +void MainWindow::handleExternalCommand(ContextHandler* handler, + const QString& parent, const QString& full, const QString& node){ + QString arguments = handler->m_arguments; + QString dir; + switch (handler->m_directoryMode) { + case ContextHandler::DM_TO_PARENT: + dir = parent; + break; + case ContextHandler::DM_TO_FILE: + dir = full; + break; + default: + dir = ui->comboBoxDirectory->currentText(); + break; + } + QMap < QString, QString > placeholders; + placeholders.insert("full", full); + placeholders.insert("node", node); + placeholders.insert("path", parent); + placeholders.insert("ext", ReQStringUtil::extensionOf(node)); + QString error; + QStringList args = arguments.split(' '); + bool hasErrors = false; + for (int ix = 0; ix < args.size(); ix++){ + QString arg = args.at(ix); + if (!ReQStringUtil::replacePlaceholders(arg, placeholders, &error)){ + guiError(NULL, error); + hasErrors = true; + break; + } + args.replace(ix, arg); + } + if (!hasErrors){ + QProcess::startDetached(handler->m_program, args, dir, NULL); + setStatusMessage(false, + tr("started:") + " " + handler->m_program + " " + arguments); + } +} + /** * Handles the global placeholder selection dialog. * @@ -388,24 +520,49 @@ void MainWindow::handlePlaceholder(QComboBox* target){ target->setCurrentText(target->currentText() + dialog.var()); } +/** + * Count the selected rows of a tableWidget and tests whether a given row is in the selection. + * + * @param table the table to test + * @param currentRow -1 or the row which will be tested whether it is a member of the selection + * @param isInSelection OUT: true: currentRow is a member of the selected rows + * + * @return the number of selected rows + */ +static int countSelectedRows(QTableWidget* table, int currentRow, + bool& isInSelection){ + int rc = 0; + isInSelection = false; + QList < QTableWidgetSelectionRange > ranges = table->selectedRanges(); + QList ::iterator it; + for (it = ranges.begin(); it != ranges.end(); ++it){ + for (int row = (*it).topRow(); row <= (*it).bottomRow(); row++){ + isInSelection = isInSelection || row == currentRow; + rc++; + } + } + return rc; +} + /** * Handles the request of a context menu of the result table. * * @param position the position of a mouse click */ void MainWindow::handleTableContextMenu(const QPoint& position){ - int row = ui->tableWidget->rowAt(position.y()); - if (row >= 0){ + int currentRow = ui->tableWidget->rowAt(position.y()); + if (currentRow >= 0){ QMenu menu; - QString node = ui->tableWidget->item(row, TC_NODE)->text(); - QString parent = buildAbsPath(row); + QString node = ui->tableWidget->item(currentRow, TC_NODE)->text(); + QString parent = buildAbsPath(currentRow); QString full = ReQStringUtil::pathAppend(parent, node); QFileInfo file(full); bool isDir = file.isDir(); QList ::const_iterator it; QMap actions; ContextHandler* handler; + bool hasSeparator = false; for (it = m_contextHandlers.list().begin(); it != m_contextHandlers.list().end(); ++it){ handler = *it; @@ -413,51 +570,35 @@ void MainWindow::handleTableContextMenu(const QPoint& position){ || (!isDir && handler->m_fileType == ContextHandler::FT_DIR)) continue; QString text = handler->m_text + " " + node; + if (handler->intrinsicType() != ContextHandler::IT_UNDEF){ + if (!hasSeparator){ + hasSeparator = true; + menu.addSeparator(); + } + bool inSelection = false; + int count = countSelectedRows(ui->tableWidget, currentRow, + inSelection); + if (inSelection) + text = handler->m_text + tr(" %1 object(s)").arg(count); + } actions.insert(menu.addAction(text), handler); } QAction* selectedItem = menu.exec( ui->tableWidget->viewport()->mapToGlobal(position)); if (selectedItem != NULL){ handler = *actions.find(selectedItem); - QString arguments = handler->m_arguments; - QString dir; - switch (handler->m_directoryMode) { - case ContextHandler::DM_TO_PARENT: - dir = parent; - break; - case ContextHandler::DM_TO_FILE: - dir = full; + switch (handler->intrinsicType()) { + case ContextHandler::IT_COPY: + handleCopyToClipboard(currentRow, full); break; + case ContextHandler::IT_UNDEF: default: - dir = ui->comboBoxDirectory->currentText(); + handleExternalCommand(handler, parent, full, node); break; } - QMap < QString, QString > placeholders; - placeholders.insert("full", full); - placeholders.insert("node", node); - placeholders.insert("path", parent); - placeholders.insert("ext", ReQStringUtil::extensionOf(node)); - QString error; - QStringList args = arguments.split(' '); - bool hasErrors = false; - for (int ix = 0; ix < args.size(); ix++){ - QString arg = args.at(ix); - if (!ReQStringUtil::replacePlaceholders(arg, placeholders, &error)){ - guiError(NULL, error); - hasErrors = true; - break; - } - args.replace(ix, arg); - } - if (!hasErrors){ - QProcess::startDetached(handler->m_program, args, dir, NULL); - setStatusMessage(false, - tr("started:") + " " + handler->m_program + " " + arguments); - } } } } - /** * Handles the event "header column clicked". * @@ -479,55 +620,6 @@ void MainWindow::headerPlaceholder(){ handlePlaceholder(ui->comboBoxHeader); } -/** - * Processes the dragging operation of the selected files in the table widget. - */ -void MainWindow::fileDragging(){ - - QDrag *drag = new QDrag(this); - QMimeData *mimeData = new QMimeData; - QList < QUrl > urls; - QList < QTableWidgetSelectionRange > ranges = - ui->tableWidget->selectedRanges(); - QList ::iterator it; - int files = 0; - int dirs = 0; - bool isDir = false; - for (it = ranges.begin(); it != ranges.end(); ++it){ - for (int row = (*it).topRow(); row <= (*it).bottomRow(); row++){ - isDir = cellAsText(row, TC_SIZE).isEmpty(); - QUrl url(buildAbsPath(row, true)); - urls.append(url); - if (isDir) - dirs++; - else - files++; - } - } - if (urls.size() > 0){ - mimeData->setUrls(urls); - drag->setMimeData(mimeData); - QPixmap image(200, 30); - QPainter painter(&image); - QString msg; - if (urls.size() == 1) - msg = tr("copy ") + ReQStringUtil::nodeOf(urls.at(0).toString()); - else if (files > 0 && dirs > 0) - msg = tr("copy %1 file(s) and %2 dir(s)").arg(files).arg(dirs); - else if (files > 0) - msg = tr("copy %1 file(s)").arg(files); - else - msg = tr("copy %1 dirs(s)").arg(dirs); - - painter.fillRect(image.rect(), Qt::white); - painter.drawText(10, 20, msg); - drag->setPixmap(image); - - Qt::DropAction dropAction = drag->exec(Qt::CopyAction); - } - -} - /** * Prepares the context menu of the result table. * @@ -567,6 +659,11 @@ msgBox.setDefaultButton(QMessageBox::Save); msgBox.exec(); } +/** + * Builds the hash with the global placeholders with their current values. + * + * @param hash IN/OUT: the placeholders will be appended here + */ void MainWindow::buildGlobalPlaceholders(QMap & hash){ hash.insert("filepatterns", ui->comboBoxFilePatterns->currentText()); @@ -582,7 +679,7 @@ hash.insert("datetime", QDateTime::currentDateTime().toLocalTime().toString("yyyy.MM.dd/hh:mm:ss")); } /** - * Replaces placeholders valid in header and footer. + * Replaces the placeholders valid in header and footer. * * @param text the text to convert * @return text with the esc sequences replaced diff --git a/appl/refind/mainwindow.hpp b/appl/refind/mainwindow.hpp index 2d15782..2a906d2 100644 --- a/appl/refind/mainwindow.hpp +++ b/appl/refind/mainwindow.hpp @@ -73,6 +73,9 @@ private: void buildGlobalPlaceholders(QMap & hash); QString cellAsText(int row, int col); void exportToStream(QTextStream& stream, int maxRow = -1); + void handleCopyToClipboard(int currentRow, const QString& full); + void handleExternalCommand(ContextHandler* handler, const QString& parent, + const QString& full, const QString& node); void handlePlaceholder(QComboBox* target); void initializeHome(); void prepareTextFind();