make web view and JavaScript engine optional

This commit is contained in:
Martchus 2016-04-21 23:55:22 +02:00
parent 2fbc7ae760
commit ec43ad8499
15 changed files with 174 additions and 52 deletions

View File

@ -45,6 +45,13 @@ bool &forceFullParse()
static bool v = false;
return v;
}
#ifndef TAGEDITOR_NO_WEBVIEW
bool &noWebView()
{
static bool v = false;
return v;
}
#endif
// file browser
bool &hideBackupFiles()
@ -308,6 +315,9 @@ void restore()
settings.beginGroup(QStringLiteral("info"));
Settings::forceFullParse() = settings.value(QStringLiteral("forcefullparse"), false).toBool();
#ifndef TAGEDITOR_NO_WEBVIEW
Settings::noWebView() = settings.value(QStringLiteral("nowebview"), false).toBool();
#endif
settings.endGroup();
settings.beginGroup(QStringLiteral("filebrowser"));
@ -436,6 +446,9 @@ void save()
settings.beginGroup(QStringLiteral("info"));
settings.setValue(QStringLiteral("forcefullparse"), Settings::forceFullParse());
#ifndef TAGEDITOR_NO_WEBVIEW
settings.setValue(QStringLiteral("nowebview"), Settings::noWebView());
#endif
settings.endGroup();
settings.beginGroup(QStringLiteral("filebrowser"));

View File

@ -43,6 +43,9 @@ enum class MultipleTagHandling
MultipleTagHandling &multipleTagHandling();
bool &hideTagSelectionComboBox();
bool &forceFullParse();
#ifndef TAGEDITOR_NO_WEBVIEW
bool &noWebView();
#endif
// file browser
bool &hideBackupFiles();

View File

@ -26,6 +26,13 @@
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="noWebViewCheckBox">
<property name="text">
<string>Don't use web view</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">

View File

@ -6,6 +6,9 @@
#include "../application/settings.h"
#include "../misc/utility.h"
#ifdef TAGEDITOR_NO_WEBVIEW
# include "../misc/htmlinfo.h"
#endif
#include "ui_mainwindow.h"
@ -440,23 +443,33 @@ void MainWindow::saveFileInformation()
{
TryLocker<> locker(fileOperationMutex());
if(locker) {
if(fileInfo().isOpen() && m_ui->tagEditorWidget->fileInfoHtml().size()) {
const QString path = QFileDialog::getSaveFileName(this, windowTitle());
if(!path.isEmpty()) {
QFile file(path);
if(file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
QTextStream stream(&file);
stream << m_ui->tagEditorWidget->fileInfoHtml();
file.close();
if(file.error() != QFileDevice::NoError) {
QMessageBox::critical(this, QApplication::applicationName(), tr("Unable to write to file.\n%1").arg(file.errorString()));
if(fileInfo().isOpen()) {
const QByteArray &htmlData =
#ifndef TAGEDITOR_NO_WEBVIEW
!Settings::noWebView() ?
m_ui->tagEditorWidget->fileInfoHtml().size() :
#endif
HtmlInfo::generateInfo(fileInfo(), m_ui->tagEditorWidget->originalNotifications());
if(!htmlData.isEmpty()) {
const QString path = QFileDialog::getSaveFileName(this, windowTitle());
if(!path.isEmpty()) {
QFile file(path);
if(file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
QTextStream stream(&file);
stream << htmlData;
file.close();
if(file.error() != QFileDevice::NoError) {
QMessageBox::critical(this, QApplication::applicationName(), tr("Unable to write to file.\n%1").arg(file.errorString()));
}
} else {
QMessageBox::critical(this, QApplication::applicationName(), tr("Unable to open file."));
}
} else {
QMessageBox::critical(this, QApplication::applicationName(), tr("Unable to open file."));
}
} else {
QMessageBox::information(this, QApplication::applicationName(), tr("No file information available."));
}
} else {
QMessageBox::information(this, QApplication::applicationName(), tr("No file information available."));
QMessageBox::information(this, QApplication::applicationName(), tr("No file is opened."));
}
} else {
m_ui->statusBar->showMessage(tr("Unable to save file information because the current process hasn't been finished yet."));

View File

@ -39,7 +39,7 @@ class MainWindow : public QMainWindow
public:
explicit MainWindow(QWidget *parent = nullptr);
virtual ~MainWindow();
~MainWindow();
// file browser
QString currentDirectory();

View File

@ -165,8 +165,12 @@ void RenameFilesDialog::startGeneratingPreview()
m_engine->generatePreview(directory(), m_ui->includeSubdirsCheckBox->isChecked());
} else {
m_engine->clearPreview();
m_ui->notificationLabel->setText(tr("The script is not valid.\nError in line %1: %3")
.arg(m_engine->errorLineNumber()).arg(m_engine->errorMessage()));
if(m_engine->errorLineNumber()) {
m_ui->notificationLabel->setText(tr("The script is not valid.\nError in line %1: %3")
.arg(m_engine->errorLineNumber()).arg(m_engine->errorMessage()));
} else {
m_ui->notificationLabel->setText(tr("An error occured when parsing the script: %1").arg(m_engine->errorMessage()));
}
m_ui->notificationLabel->setNotificationType(NotificationType::Warning);
}
} else {

View File

@ -43,8 +43,8 @@ private slots:
void showPreviewProgress(int itemsProcessed, int errorsOccured);
void showPreviewResults();
void showChangsingsResults();
void currentItemSelected(const QItemSelection & selected, const QItemSelection & deselected);
void previewItemSelected(const QItemSelection & selected, const QItemSelection & deselected);
void currentItemSelected(const QItemSelection &selected, const QItemSelection &deselected);
void previewItemSelected(const QItemSelection &selected, const QItemSelection &deselected);
void pasteScriptFromFile(const QString &fileName);
void pasteScriptFromClipboard();
void pasteDefaultExampleScript();

View File

@ -265,6 +265,9 @@ bool InfoOptionPage::apply()
{
if(hasBeenShown()) {
Settings::forceFullParse() = ui()->forceFullParseCheckBox->isChecked();
#ifndef TAGEDITOR_NO_WEBVIEW
Settings::noWebView() = ui()->noWebViewCheckBox->isChecked();
#endif
}
return true;
}
@ -273,6 +276,12 @@ void InfoOptionPage::reset()
{
if(hasBeenShown()) {
ui()->forceFullParseCheckBox->setChecked(Settings::forceFullParse());
#ifdef TAGEDITOR_NO_WEBVIEW
ui()->noWebViewCheckBox->setChecked(true);
ui()->noWebViewCheckBox->setEnabled(false);
#else
ui()->noWebViewCheckBox->setChecked(Settings::noWebView());
#endif
}
}

View File

@ -78,7 +78,7 @@ enum LoadingResult : char
*/
TagEditorWidget::TagEditorWidget(QWidget *parent) :
QWidget(parent),
m_ui(new Ui::TagEditorWidget()),
m_ui(new Ui::TagEditorWidget),
m_nextFileAfterSaving(false),
m_makingResultsAvailable(false),
m_abortClicked(false)
@ -86,14 +86,8 @@ TagEditorWidget::TagEditorWidget(QWidget *parent) :
// setup UI
m_ui->setupUi(this);
makeHeading(m_ui->fileNameLabel);
// setup web view
#ifndef TAGEDITOR_NO_WEBVIEW
m_infoWebView = new WEB_VIEW_PROVIDER(m_ui->tagSplitter);
m_infoWebView->setAcceptDrops(false);
m_infoWebView->setContextMenuPolicy(Qt::CustomContextMenu);
connect(m_infoWebView, &QWidget::customContextMenuRequested, this, &TagEditorWidget::showInfoWebViewContextMenu);
m_ui->tagSplitter->addWidget(m_infoWebView);
#endif
// setup (web) view
initInfoView();
// setup file watcher
m_fileWatcher = new QFileSystemWatcher(this);
m_fileChangedOnDisk = false;
@ -193,7 +187,7 @@ bool TagEditorWidget::event(QEvent *event)
{
switch(event->type()) {
case QEvent::PaletteChange:
updateInfoWebView();
updateInfoView();
break;
case QEvent::DragEnter:
case QEvent::Drop: {
@ -446,7 +440,9 @@ void TagEditorWidget::updateFileStatusStatus()
m_ui->stackedWidget->setEnabled(hasTag);
// webview
#ifndef TAGEDITOR_NO_WEBVIEW
m_infoWebView->setEnabled(opened);
if(m_infoWebView) {
m_infoWebView->setEnabled(opened);
}
#endif
// inform the main window about the file status change as well
emit fileStatusChange(opened, hasTag);
@ -542,22 +538,41 @@ void TagEditorWidget::insertTitleFromFilename()
}
}
/*!
* \brief Updates the info web view to show information about the
* currently opened file.
*/
void TagEditorWidget::updateInfoWebView()
void TagEditorWidget::initInfoView()
{
#ifndef TAGEDITOR_NO_WEBVIEW
if(m_fileInfo.isOpen()) {
m_fileInfoHtml = HtmlInfo::generateInfo(m_fileInfo, m_originalNotifications);
m_infoWebView->setContent(m_fileInfoHtml, QStringLiteral("application/xhtml+xml"));
} else {
m_infoWebView->setUrl(QStringLiteral("about:blank"));
if(!Settings::noWebView() && !m_infoWebView) {
m_infoWebView = new WEB_VIEW_PROVIDER(m_ui->tagSplitter);
m_infoWebView->setAcceptDrops(false);
m_infoWebView->setContextMenuPolicy(Qt::CustomContextMenu);
connect(m_infoWebView, &QWidget::customContextMenuRequested, this, &TagEditorWidget::showInfoWebViewContextMenu);
m_ui->tagSplitter->addWidget(m_infoWebView);
} else if(Settings::noWebView() && m_infoWebView) {
m_infoWebView->deleteLater();
m_infoWebView = nullptr;
}
#endif
}
/*!
* \brief Updates the info web view to show information about the
* currently opened file.
*/
void TagEditorWidget::updateInfoView()
{
#ifndef TAGEDITOR_NO_WEBVIEW
if(m_infoWebView) {
if(m_fileInfo.isOpen()) {
m_fileInfoHtml = HtmlInfo::generateInfo(m_fileInfo, m_originalNotifications);
m_infoWebView->setContent(m_fileInfoHtml, QStringLiteral("application/xhtml+xml"));
} else {
m_infoWebView->setUrl(QStringLiteral("about:blank"));
}
}
#endif
}
#ifndef TAGEDITOR_NO_WEBVIEW
/*!
* \brief Shows the context menu for the info web view.
*/
@ -578,6 +593,7 @@ void TagEditorWidget::copyInfoWebViewSelection()
{
QApplication::clipboard()->setText(m_infoWebView->selectedText());
}
#endif
/*!
* \brief Calls the specified \a function for each of the currently present tag edits.
@ -719,7 +735,7 @@ void TagEditorWidget::showFile(char result)
emit statusMessage(statusMsg);
} else {
// update webview
updateInfoWebView();
updateInfoView();
// show parsing status/result using parsing notification widget
auto worstNotificationType = m_fileInfo.worstNotificationTypeIncludingRelatedObjects();
if(worstNotificationType >= Media::NotificationType::Critical) {
@ -1131,6 +1147,9 @@ void TagEditorWidget::applySettingsFromDialog()
break;
}
m_ui->actionManage_tags_automatically_when_loading_file->setChecked(Settings::autoTagManagement());
// ensure info view is displayed/not displayed according to settings
initInfoView();
updateInfoView();
}
/*!

View File

@ -12,11 +12,12 @@
#include <functional>
#if defined(TAGEDITOR_NO_WEBVIEW)
# error "not supported (yet)."
#elif defined(TAGEDITOR_USE_WEBENGINE)
# define WEB_VIEW_PROVIDER QWebEngineView
#else
#elif defined(TAGEDITOR_USE_WEBKIT)
# define WEB_VIEW_PROVIDER QWebView
#else
# error "Macro for WebView provider not specified."
#endif
QT_FORWARD_DECLARE_CLASS(QFileSystemWatcher)
@ -53,6 +54,7 @@ public:
QMutex &fileOperationMutex();
const QString &currentPath() const;
Media::MediaFileInfo &fileInfo();
Media::NotificationList &originalNotifications();
bool isTagEditShown() const;
const QByteArray &fileInfoHtml() const;
bool isFileNameVisible() const;
@ -110,10 +112,13 @@ private slots:
// saving
void showSavingResult(bool processingError, bool ioError);
// web view
void updateInfoWebView();
// info (web) view
void initInfoView();
void updateInfoView();
#ifndef TAGEDITOR_NO_WEBVIEW
void showInfoWebViewContextMenu(const QPoint &);
void copyInfoWebViewSelection();
#endif
private:
void updateDocumentTitleEdits();
@ -131,7 +136,9 @@ private:
QMenu *m_addTagMenu;
QMenu *m_removeTagMenu;
QMenu *m_changeTargetMenu;
#ifndef TAGEDITOR_NO_WEBVIEW
WEB_VIEW_PROVIDER *m_infoWebView;
#endif
// tag, file, directory management
QString m_currentPath;
QFileSystemWatcher *m_fileWatcher;
@ -176,6 +183,14 @@ inline Media::MediaFileInfo &TagEditorWidget::fileInfo()
return m_fileInfo;
}
/*!
* \brief Returns the original notifications.
*/
inline Media::NotificationList &TagEditorWidget::originalNotifications()
{
return m_originalNotifications;
}
/*!
* \brief Returns the HTML source of the info website.
*/

View File

@ -18,8 +18,10 @@ namespace RenamingUtility {
RemamingEngine::RemamingEngine(QObject *parent) :
QObject(parent),
#ifndef TAGEDITOR_NO_JSENGINE
m_tagEditorQObj(new TagEditorObject(&m_engine)),
m_tagEditorJsObj(TAGEDITOR_JS_QOBJECT(m_engine, m_tagEditorQObj)),
#endif
m_itemsProcessed(0),
m_errorsOccured(0),
m_aborted(false),
@ -28,11 +30,14 @@ RemamingEngine::RemamingEngine(QObject *parent) :
m_currentModel(nullptr),
m_previewModel(nullptr)
{
#ifndef TAGEDITOR_NO_JSENGINE
m_engine.globalObject().setProperty(QStringLiteral("tageditor"), m_tagEditorJsObj);
#endif
connect(this, &RemamingEngine::previewGenerated, this, &RemamingEngine::processPreviewGenerated);
connect(this, &RemamingEngine::changingsApplied, this, &RemamingEngine::processChangingsApplied);
}
#ifndef TAGEDITOR_NO_JSENGINE
bool RemamingEngine::setProgram(const TAGEDITOR_JS_VALUE &program)
{
if(TAGEDITOR_JS_IS_VALID_PROG(program)) {
@ -49,14 +54,22 @@ bool RemamingEngine::setProgram(const TAGEDITOR_JS_VALUE &program)
}
return false;
}
#endif
bool RemamingEngine::setProgram(const QString &program)
{
#ifndef TAGEDITOR_NO_JSENGINE
return setProgram(m_engine.evaluate(QStringLiteral("(function(){") % program % QStringLiteral("})")));
#else
m_errorLineNumber = 0;
m_errorMessage = tr("Not compiled with ECMA support.");
return false;
#endif
}
bool RemamingEngine::generatePreview(const QDir &rootDirectory, bool includeSubdirs)
{
#ifndef TAGEDITOR_NO_JSENGINE
TryLocker<> locker(m_mutex);
if(locker) {
setRootItem();
@ -76,6 +89,9 @@ bool RemamingEngine::generatePreview(const QDir &rootDirectory, bool includeSubd
} else {
return false;
}
#else
return false;
#endif
}
bool RemamingEngine::applyChangings()
@ -183,6 +199,7 @@ void RemamingEngine::updateModel(FileSystemItem *rootItem)
}
}
#ifndef TAGEDITOR_NO_JSENGINE
unique_ptr<FileSystemItem> RemamingEngine::generatePreview(const QDir &dir, FileSystemItem *parent)
{
auto item = make_unique<FileSystemItem>(ItemStatus::Current, ItemType::Dir, dir.dirName(), parent);
@ -215,6 +232,7 @@ unique_ptr<FileSystemItem> RemamingEngine::generatePreview(const QDir &dir, File
emit progress(m_itemsProcessed, m_errorsOccured);
return item;
}
#endif
void RemamingEngine::applyChangings(FileSystemItem *parentItem)
{
@ -298,6 +316,7 @@ void RemamingEngine::setError(const QList<FileSystemItem *> items)
}
}
#ifndef TAGEDITOR_NO_JSENGINE
void RemamingEngine::executeScriptForItem(const QFileInfo &fileInfo, FileSystemItem *item)
{
// make file info for the specified item available in the script
@ -359,5 +378,6 @@ void RemamingEngine::executeScriptForItem(const QFileInfo &fileInfo, FileSystemI
}
}
}
#endif
} // namespace RenamingUtility

View File

@ -9,10 +9,10 @@
#include <QDir>
#include <QMutex>
#include <QAtomicInteger>
#if TAGEDITOR_USE_JSENGINE
#if defined(TAGEDITOR_USE_JSENGINE)
# include <QJSEngine>
# include <QJSValue>
#else
#elif defined(TAGEDITOR_USE_SCRIPT)
# include <QScriptEngine>
# include <QScriptValue>
#endif
@ -35,8 +35,10 @@ public:
RemamingEngine(QObject *parent = nullptr);
FileSystemItem *rootItem() const;
#ifndef TAGEDITOR_NO_JSENGINE
const TAGEDITOR_JS_VALUE &scriptProgram() const;
bool setProgram(const TAGEDITOR_JS_VALUE &program);
#endif
bool setProgram(const QString &program);
const QDir &rootDirectory() const;
bool subdirsIncluded() const;
@ -66,20 +68,28 @@ private slots:
private:
void setRootItem(std::unique_ptr<FileSystemItem> &&rootItem = std::unique_ptr<FileSystemItem>());
void updateModel(FileSystemItem *rootItem);
#ifndef TAGEDITOR_NO_JSENGINE
std::unique_ptr<FileSystemItem> generatePreview(const QDir &dir, FileSystemItem *parent = nullptr);
#endif
void applyChangings(FileSystemItem *parentItem);
static void setError(const QList<FileSystemItem *> items);
#ifndef TAGEDITOR_NO_JSENGINE
void executeScriptForItem(const QFileInfo &fileInfo, FileSystemItem *item);
#endif
#ifndef TAGEDITOR_NO_JSENGINE
TagEditorObject *m_tagEditorQObj;
TAGEDITOR_JS_ENGINE m_engine;
TAGEDITOR_JS_VALUE m_tagEditorJsObj;
#endif
std::unique_ptr<FileSystemItem> m_rootItem;
std::unique_ptr<FileSystemItem> m_newlyGeneratedRootItem;
int m_itemsProcessed;
int m_errorsOccured;
QAtomicInteger<unsigned char> m_aborted;
#ifndef TAGEDITOR_NO_JSENGINE
TAGEDITOR_JS_VALUE m_program;
#endif
QDir m_dir;
bool m_includeSubdirs;
QMutex m_mutex;
@ -95,10 +105,12 @@ inline FileSystemItem *RemamingEngine::rootItem() const
return m_rootItem.get();
}
#ifndef TAGEDITOR_NO_JSENGINE
inline const TAGEDITOR_JS_VALUE &RemamingEngine::scriptProgram() const
{
return m_program;
}
#endif
inline const QDir &RemamingEngine::rootDirectory() const
{

View File

@ -3,7 +3,7 @@
#include <QtGlobal>
#if TAGEDITOR_USE_JSENGINE
#if defined(TAGEDITOR_USE_JSENGINE)
# define TAGEDITOR_JS_ENGINE QJSEngine
# define TAGEDITOR_JS_VALUE QJSValue
# define TAGEDITOR_JS_READONLY
@ -13,7 +13,7 @@
# define TAGEDITOR_JS_IS_VALID_PROG(program) (!program.isError() && program.isCallable())
QT_FORWARD_DECLARE_CLASS(QJSValue)
QT_FORWARD_DECLARE_CLASS(QJSEngine)
#else
#elif defined(TAGEDITOR_USE_SCRIPT)
# define TAGEDITOR_JS_ENGINE QScriptEngine
# define TAGEDITOR_JS_VALUE QScriptValue
# define TAGEDITOR_JS_READONLY ,QScriptValue::ReadOnly

View File

@ -1,3 +1,5 @@
#ifndef TAGEDITOR_NO_JSENGINE
#include "./tageditorobject.h"
#include "./filesystemitem.h"
@ -12,10 +14,10 @@
#include <QDir>
#ifdef TAGEDITOR_USE_JSENGINE
#if defined(TAGEDITOR_USE_JSENGINE)
# include <QJSEngine>
# include <QJSValue>
#else
#elif defined(TAGEDITOR_USE_SCRIPT)
# include <QScriptEngine>
# include <QScriptValue>
#endif
@ -248,3 +250,5 @@ void TagEditorObject::skip()
}
} // namespace RenamingUtility
#endif

View File

@ -1,12 +1,14 @@
#ifndef RENAMINGUTILITY_SCRIPTFUNCTIONS_H
#define RENAMINGUTILITY_SCRIPTFUNCTIONS_H
#ifndef TAGEDITOR_NO_JSENGINE
#include "./scriptdefs.h"
#include <QObject>
#ifdef TAGEDITOR_USE_JSENGINE
#if defined(TAGEDITOR_USE_JSENGINE)
# include <QJSValue>
#else
#elif defined(TAGEDITOR_USE_SCRIPT)
# include <QScriptValue>
#endif
@ -72,4 +74,5 @@ inline ActionType TagEditorObject::action() const
} // namespace RenamingUtility
#endif // TAGEDITOR_NO_JSENGINE
#endif // RENAMINGUTILITY_SCRIPTFUNCTIONS_H