diff --git a/CMakeLists.txt b/CMakeLists.txt index 8a20d03..bf61dd6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,91 +1,93 @@ cmake_minimum_required(VERSION 3.5) # KDE Application Version, managed by release script set(KDE_APPLICATIONS_VERSION_MAJOR "19") set(KDE_APPLICATIONS_VERSION_MINOR "11") set(KDE_APPLICATIONS_VERSION_MICRO "70") set(KDE_APPLICATIONS_VERSION "${KDE_APPLICATIONS_VERSION_MAJOR}.${KDE_APPLICATIONS_VERSION_MINOR}.${KDE_APPLICATIONS_VERSION_MICRO}") project(step VERSION ${KDE_APPLICATIONS_VERSION}) find_package(ECM 1.7.0 REQUIRED NO_MODULE) find_package(KF5DocTools) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR}) set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules" ${CMAKE_MODULE_PATH}) include(KDEInstallDirs) include(ECMAddTests) include(KDECompilerSettings NO_POLICY_SCOPE) include(KDECMakeSettings) include(ECMInstallIcons) include(ECMOptionalAddSubdirectory) include(ECMSetupVersion) include(FeatureSummary) include(ECMPoQmTools) find_package(Qt5 5.2 REQUIRED NO_MODULE COMPONENTS Xml Svg OpenGL Test ) find_package(KF5 REQUIRED COMPONENTS Crash - KHtml Config + I18n IconThemes + KIO NewStuff Plotting + TextWidgets ) find_package(Eigen3 3.2.2 REQUIRED) find_package(GSL) find_package(Qalculate) set_package_properties(EIGEN3 PROPERTIES - DESCRIPTION "Eigen3" + DESCRIPTION "Eigen3" URL "http://eigen.tuxfamily.org" TYPE OPTIONAL PURPOSE "Required to build step") set_package_properties(QALCULATE PROPERTIES # REQUIRED_VERSION "0.9.5" - DESCRIPTION "Qalculate" + DESCRIPTION "Qalculate" URL "http://qalculate.sourceforge.net/" TYPE OPTIONAL PURPOSE "Unit conversion support in Step") set_package_properties(GSL PROPERTIES # REQUIRED_VERSION "1.8" - DESCRIPTION "GSL" + DESCRIPTION "GSL" URL "http://eigen.tuxfamily.org" TYPE OPTIONAL PURPOSE "Provides a GSL-powered solver for Step") set(STEPCORE_WITH_GSL ${GSL_FOUND} CACHE BOOL "Enable GSL-powered features for StepCore") set(STEPCORE_WITH_QT ON) # CACHE BOOL "Enable QT-powered features for StepCore") set(STEP_WITH_QALCULATE ${QALCULATE_FOUND} CACHE BOOL "Enable unit conversion support using libqalculate") # These settings are forced by Eigen2 creating many many warnings without them. # FIXME: How can we make Eigen behave and not need them? set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-local-typedefs") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-parameter") include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${EIGEN3_INCLUDE_DIR}) add_definitions(-DQT_NO_URL_CAST_FROM_STRING) if(KF5DocTools_FOUND) ecm_optional_add_subdirectory(doc) endif() add_subdirectory(stepcore) add_subdirectory(step) add_subdirectory(autotests) install(FILES org.kde.step.appdata.xml DESTINATION ${KDE_INSTALL_METAINFODIR}) find_package(SharedMimeInfo REQUIRED) install(FILES org.kde.step.xml DESTINATION ${XDG_MIME_INSTALL_DIR}) update_xdg_mimetypes(${XDG_MIME_INSTALL_DIR}) feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES) diff --git a/step/CMakeLists.txt b/step/CMakeLists.txt index 59a876c..c3c4418 100644 --- a/step/CMakeLists.txt +++ b/step/CMakeLists.txt @@ -1,92 +1,96 @@ ecm_setup_version(${KDE_APPLICATIONS_VERSION} VARIABLE_PREFIX STEP VERSION_HEADER step_version.h) set(step_SRCS arrow.cc clipboard.cc mainwindow.cc worldmodel.cc worldscene.cc worldgraphics.cc worldbrowser.cc propertiesbrowser.cc infobrowser.cc undobrowser.cc itempalette.cc worldfactory.cc stepgraphicsitem.cc particlegraphics.cc polygongraphics.cc gasgraphics.cc gascreationdialog.cc softbodygraphics.cc springgraphics.cc motorgraphics.cc jointgraphics.cc toolgraphics.cc simulationthread.cc unitscalc.cc latexformula.cc messageframe.cc main.cc choicesmodel.cc ) set(step_UIS create_gas_particles.ui create_softbody_items.ui configure_graph.ui configure_meter.ui configure_controller.ui configure_step_general.ui) set(step_KCFGS settings.kcfgc) if(STEPCORE_WITH_QT) add_definitions(-DSTEPCORE_WITH_QT) endif(STEPCORE_WITH_QT) if(STEPCORE_WITH_GSL) add_definitions(-DSTEPCORE_WITH_GSL) endif(STEPCORE_WITH_GSL) if(STEP_WITH_QALCULATE) add_definitions(-DSTEP_WITH_QALCULATE) add_definitions(-DSTEP_WITH_UNITSCALC) add_definitions(${QALCULATE_CFLAGS}) set(qalculate_LIBS ${QALCULATE_LIBRARIES} ${CLN_LIBRARIES}) # To compile with libcln string (REPLACE "-fno-exceptions" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") add_definitions (-fexceptions) endif(STEP_WITH_QALCULATE) -ki18n_wrap_ui( step_SRCS ${step_UIS} ) -kconfig_add_kcfg_files( step_SRCS ${step_KCFGS} ) +qt5_add_resources(step_SRCS data/resources.qrc) +ki18n_wrap_ui(step_SRCS ${step_UIS}) +kconfig_add_kcfg_files(step_SRCS ${step_KCFGS}) include_directories(${CMAKE_CURRENT_BINARY_DIR}) include_directories(${CMAKE_CURRENT_SOURCE_DIR}) ecm_create_qm_loader(step_SRCS step_qt) add_executable(step ${step_SRCS}) target_link_libraries(step stepcore KF5::Crash + KF5::I18n KF5::IconThemes - KF5::KHtml + KF5::KIOCore + KF5::KIOWidgets + KF5::TextWidgets KF5::Plotting KF5::NewStuff Qt5::OpenGL Qt5::Widgets ${qalculate_LIBS}) install(TARGETS step ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) install(FILES step.kcfg DESTINATION ${KDE_INSTALL_KCFGDIR}) install(FILES stepui.rc DESTINATION ${KDE_INSTALL_KXMLGUI5DIR}/step) install(FILES step.knsrc DESTINATION ${KDE_INSTALL_CONFDIR}) install( PROGRAMS org.kde.step.desktop DESTINATION ${KDE_INSTALL_APPDIR} ) add_subdirectory(icons) add_subdirectory(data) diff --git a/step/data/CMakeLists.txt b/step/data/CMakeLists.txt index 8100805..57c0b6f 100644 --- a/step/data/CMakeLists.txt +++ b/step/data/CMakeLists.txt @@ -1,71 +1,71 @@ if(CURRENT_LANG) set(STEP_BUILD_TRANSLATIONS 1) endif(CURRENT_LANG) if(STEP_BUILD_TRANSLATIONS) find_package(PythonInterp) set(EXTRACTXML_EXECUTABLE ${CMAKE_CURRENT_SOURCE_DIR}/extractxml) if(PYTHON_EXECUTABLE) # STEP_PROCESS_XML_TRANSLATION( [ALL] [INSTALL_DESTINATION ] ...) macro(STEP_PROCESS_XML_TRANSLATION _lang _po_file _extractxml_args) set(_xmlfiles_tr) set(_args ${ARGN}) set(_addToAll) set(_installDest) list(GET _args 0 _tmp) if("${_tmp}" STREQUAL "ALL") set(_addToAll ALL) list(REMOVE_AT _args 0) endif("${_tmp}" STREQUAL "ALL") - + list(GET _args 0 _tmp) if("${_tmp}" STREQUAL "INSTALL_DESTINATION") list(GET _args 1 _installDest ) list(REMOVE_AT _args 0 1) endif("${_tmp}" STREQUAL "INSTALL_DESTINATION") if(EXISTS ${_po_file}) get_filename_component(_po_file_we ${_po_file} NAME_WE) set(_mo_file ${CMAKE_CURRENT_BINARY_DIR}/${_po_file_we}.mo) add_custom_command(OUTPUT ${_mo_file} COMMAND ${GETTEXT_MSGFMT_EXECUTABLE} -o ${_mo_file} ${_po_file} WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" DEPENDS ${_po_file} ) foreach(_xmlfile ${_args}) get_filename_component(_xmlfile_basename ${_xmlfile} NAME) set(_xmlfile_tr ${CMAKE_CURRENT_BINARY_DIR}/${_xmlfile_basename}) set(_extractxml_args_copy ${_extractxml_args}) separate_arguments(_extractxml_args_copy) add_custom_command(OUTPUT ${_xmlfile_tr} COMMAND ${EXTRACTXML_EXECUTABLE} --translate --mo-file=${_mo_file} --output-dir=${CMAKE_CURRENT_BINARY_DIR} ${_extractxml_args_copy} ${_xmlfile} WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" DEPENDS ${_xmlfile} ${_mo_file} ) if(_installDest) install(FILES ${_xmlfile_tr} DESTINATION ${_installDest}/${_lang}) endif(_installDest) list(APPEND _xmlfiles_tr ${_xmlfile_tr}) endforeach(_xmlfile) add_custom_target(xmlfiles_tr ${_addToAll} DEPENDS ${_xmlfiles_tr}) endif(EXISTS ${_po_file}) endmacro(STEP_PROCESS_XML_TRANSLATION) else(PYTHON_EXECUTABLE) message("Python executable NOT found - Step data translations will not be build") macro(STEP_PROCESS_XML_TRANSLATION) endmacro(STEP_PROCESS_XML_TRANSLATION) endif(PYTHON_EXECUTABLE) endif(STEP_BUILD_TRANSLATIONS) -add_subdirectory(objinfo) +add_subdirectory(objectinfo) add_subdirectory(examples) add_subdirectory(tutorials) diff --git a/step/data/objinfo/CMakeLists.txt b/step/data/objectinfo/CMakeLists.txt similarity index 76% rename from step/data/objinfo/CMakeLists.txt rename to step/data/objectinfo/CMakeLists.txt index 7f8ecf5..db13b60 100644 --- a/step/data/objinfo/CMakeLists.txt +++ b/step/data/objectinfo/CMakeLists.txt @@ -1,17 +1,10 @@ FILE(GLOB INFO_HTML_FILES "*.html") if(STEP_BUILD_TRANSLATIONS) set(po_file ${CMAKE_SOURCE_DIR}/messages/kdeedu/step_objinfo_files.po) STEP_PROCESS_XML_TRANSLATION(${CURRENT_LANG} ${po_file} "--context='%(filename)s:%(tag)s' --tag-regex='^(?:title|body|p|h[1-6])$$' --recursive --strip" ALL INSTALL_DESTINATION ${KDE_INSTALL_DATADIR}/step/objinfo ${INFO_HTML_FILES}) - -else(STEP_BUILD_TRANSLATIONS) - - install(FILES - ${INFO_HTML_FILES} - DESTINATION ${KDE_INSTALL_DATADIR}/step/objinfo) - endif(STEP_BUILD_TRANSLATIONS) diff --git a/step/data/objinfo/Anchor.html b/step/data/objectinfo/anchor.html similarity index 100% rename from step/data/objinfo/Anchor.html rename to step/data/objectinfo/anchor.html diff --git a/step/data/objinfo/Box.html b/step/data/objectinfo/box.html similarity index 100% rename from step/data/objinfo/Box.html rename to step/data/objectinfo/box.html diff --git a/step/data/objinfo/ChargedParticle.html b/step/data/objectinfo/chargedparticle.html similarity index 100% rename from step/data/objinfo/ChargedParticle.html rename to step/data/objectinfo/chargedparticle.html diff --git a/step/data/objinfo/CoulombForce.html b/step/data/objectinfo/coulombforce.html similarity index 81% rename from step/data/objinfo/CoulombForce.html rename to step/data/objectinfo/coulombforce.html index 73a87d4..81f9642 100644 --- a/step/data/objinfo/CoulombForce.html +++ b/step/data/objectinfo/coulombforce.html @@ -1,14 +1,14 @@ Coulomb Force

Coulomb force is a force of interaction between charged particles.

Coulomb's law

  • The magnitude of the electrostatic force between two point electric charges is directly proportional to the product of the magnitudes of each of the charges and inversely proportional to the square of the distance between the two charges.
  • -

    For more details, please refer to the Coulomb Force.

    +

    For more details, please refer to the Coulomb Force.

    diff --git a/step/data/objinfo/Disk.html b/step/data/objectinfo/disk.html similarity index 100% rename from step/data/objinfo/Disk.html rename to step/data/objectinfo/disk.html diff --git a/step/data/objinfo/Gas.html b/step/data/objectinfo/gas.html similarity index 80% rename from step/data/objinfo/Gas.html rename to step/data/objectinfo/gas.html index 1c3c653..04d42a3 100644 --- a/step/data/objinfo/Gas.html +++ b/step/data/objectinfo/gas.html @@ -1,12 +1,12 @@ Gas

    A gas is a collection of gasoline particles. Associated with the gas is a force. To add gas particles rightclick the gas and click on "Create particles".

    -

    For details about the math used to calculate the forces, please refer to the Lennard-Jones potential.

    +

    For details about the math used to calculate the forces, please refer to the Lennard-Jones potential.

    diff --git a/step/data/objinfo/GasLJForce.html b/step/data/objectinfo/gasljforce.html similarity index 78% rename from step/data/objinfo/GasLJForce.html rename to step/data/objectinfo/gasljforce.html index ce5d227..3e29276 100644 --- a/step/data/objinfo/GasLJForce.html +++ b/step/data/objectinfo/gasljforce.html @@ -1,17 +1,17 @@ Force -

    This force simulates the Lennard-Jones potential. There are three parameters for this force:

    +

    This force simulates the Lennard-Jones potential. There are three parameters for this force:

    • depth: The minimum value of the Lennard-Jones potential wall
    • rmin: The distance from the origin to the minimum of the potential
    • cutoff: The distance, where the Lennard-Jones (LJ) potential is often truncated to save computational time

    These parameters are empirical and are usually obtained from experiment or some rough estimation.

    diff --git a/step/data/objinfo/GasParticle.html b/step/data/objectinfo/gasparticle.html similarity index 100% rename from step/data/objinfo/GasParticle.html rename to step/data/objectinfo/gasparticle.html diff --git a/step/data/objinfo/GravitationForce.html b/step/data/objectinfo/gravitationforce.html similarity index 84% rename from step/data/objinfo/GravitationForce.html rename to step/data/objectinfo/gravitationforce.html index 1c8fe88..f9201d2 100644 --- a/step/data/objinfo/GravitationForce.html +++ b/step/data/objectinfo/gravitationforce.html @@ -1,16 +1,16 @@ Gravitation Force

    Gravitational force is an attractive force that act between bodies having mass.

    Newton's law

  • Every body in the universe attracts every other body with a force, which is proportional to the product of the masses of the bodies and inversely proportional to square of the distance between them.
  • General relativity

  • In general relativity gravitation is explained on the basis of curvature of space-time.
  • -

    For more details, please refer to the Gravitation Force.

    +

    For more details, please refer to the Gravitation Force.

    diff --git a/step/data/objinfo/LinearMotor.html b/step/data/objectinfo/linearmotor.html similarity index 100% rename from step/data/objinfo/LinearMotor.html rename to step/data/objectinfo/linearmotor.html diff --git a/step/data/objinfo/Meter.html b/step/data/objectinfo/meter.html similarity index 100% rename from step/data/objinfo/Meter.html rename to step/data/objectinfo/meter.html diff --git a/step/data/objinfo/Note.html b/step/data/objectinfo/note.html similarity index 100% rename from step/data/objinfo/Note.html rename to step/data/objectinfo/note.html diff --git a/step/data/objinfo/Particle.html b/step/data/objectinfo/particle.html similarity index 100% rename from step/data/objinfo/Particle.html rename to step/data/objectinfo/particle.html diff --git a/step/data/objinfo/Pin.html b/step/data/objectinfo/pin.html similarity index 100% rename from step/data/objinfo/Pin.html rename to step/data/objectinfo/pin.html diff --git a/step/data/objinfo/Polygon.html b/step/data/objectinfo/polygon.html similarity index 100% rename from step/data/objinfo/Polygon.html rename to step/data/objectinfo/polygon.html diff --git a/step/data/objinfo/Spring.html b/step/data/objectinfo/spring.html similarity index 100% rename from step/data/objinfo/Spring.html rename to step/data/objectinfo/spring.html diff --git a/step/data/objinfo/WeightForce.html b/step/data/objectinfo/weightforce.html similarity index 80% rename from step/data/objinfo/WeightForce.html rename to step/data/objectinfo/weightforce.html index 154515d..0314449 100644 --- a/step/data/objinfo/WeightForce.html +++ b/step/data/objectinfo/weightforce.html @@ -1,15 +1,15 @@ Weight Force

    Weight of an object is the force exerted on it by gravity.

    Weight is a vector quantity. It is often denoted by W and given by the relation W = mg.

  • Where, m is the mass of the body
  • and g is the acceleration due to gravity.
  • -

    For more details, please refer to the Weight Force.

    +

    For more details, please refer to the Weight Force.

    diff --git a/step/data/objinfo/World.html b/step/data/objectinfo/world.html similarity index 100% rename from step/data/objinfo/World.html rename to step/data/objectinfo/world.html diff --git a/step/data/resources.qrc b/step/data/resources.qrc new file mode 100644 index 0000000..3c1f6b6 --- /dev/null +++ b/step/data/resources.qrc @@ -0,0 +1,22 @@ + + + objectinfo/anchor.html + objectinfo/box.html + objectinfo/chargedparticle.html + objectinfo/coulombforce.html + objectinfo/disk.html + objectinfo/gas.html + objectinfo/gasljforce.html + objectinfo/gasparticle.html + objectinfo/gravitationforce.html + objectinfo/linearmotor.html + objectinfo/meter.html + objectinfo/note.html + objectinfo/particle.html + objectinfo/pin.html + objectinfo/polygon.html + objectinfo/spring.html + objectinfo/weightforce.html + objectinfo/world.html + + diff --git a/step/infobrowser.cc b/step/infobrowser.cc index 690817d..cffdb3e 100644 --- a/step/infobrowser.cc +++ b/step/infobrowser.cc @@ -1,425 +1,256 @@ /* This file is part of Step. Copyright (C) 2007 Vladimir Kuznetsov Step is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Step is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Step; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "infobrowser.h" #include "worldmodel.h" #include "settings.h" #include #include #include #include #include #include -#include #include #include #include #include #include InfoBrowser::InfoBrowser(WorldModel* worldModel, QWidget* parent) : QDockWidget(i18n("Context info"), parent), - _worldModel(worldModel), _wikiJob(NULL), _wikiFromHistory(false), _selectionChanged(false) + _worldModel(worldModel), _selectionChanged(false) { QWidget* widget = new QWidget(this); setWidget(widget); QVBoxLayout* layout = new QVBoxLayout(widget); layout->setContentsMargins(0,0,0,0); layout->setSpacing(0); _toolBar = new KToolBar(widget); layout->addWidget(_toolBar); _toolBar->setMovable(false); _toolBar->setFloatable(false); _toolBar->setIconDimensions(16); _toolBar->setContextMenuPolicy(Qt::NoContextMenu); _toolBar->setToolButtonStyle(Qt::ToolButtonIconOnly); _backAction = _toolBar->addAction(QIcon::fromTheme(QStringLiteral("go-previous")), i18n("Back"), this, SLOT(back())); _backAction->setEnabled(false); _forwardAction = _toolBar->addAction(QIcon::fromTheme(QStringLiteral("go-next")), i18n("Forward"), this, SLOT(forward())); _forwardAction->setEnabled(false); _toolBar->addSeparator(); _syncAction = _toolBar->addAction(QIcon::fromTheme(QStringLiteral("goto-page")), i18n("Sync selection"), this, SLOT(syncSelection())); // XXX: icon _syncAction->setEnabled(false); _followAction = _toolBar->addAction(QIcon::fromTheme(QStringLiteral("note2")), i18n("Follow selection")/*, this, SLOT(syncSelection(bool))*/); // XXX: icon _followAction->setCheckable(true); _followAction->setChecked(true); _toolBar->addSeparator(); _execAction = _toolBar->addAction(QIcon::fromTheme(QStringLiteral("system-run")), i18n("Open in browser"), this, SLOT(openInBrowser())); _execAction->setEnabled(false); - _htmlPart = new KHTMLPart(widget); - layout->addWidget(_htmlPart->widget()); + _htmlBrowser = new QTextBrowser(widget); + _htmlBrowser->setOpenLinks(false); + layout->addWidget(_htmlBrowser); - _htmlPart->setJavaEnabled(false); - _htmlPart->setPluginsEnabled(false); - _htmlPart->setJScriptEnabled(true); - _htmlPart->setMetaRefreshEnabled(true); - _htmlPart->setDNDEnabled(false); - - connect(_htmlPart->browserExtension(), - SIGNAL(openUrlRequest(QUrl,KParts::OpenUrlArguments,KParts::BrowserArguments)), - this, SLOT(openUrl(QUrl))); + connect(_htmlBrowser, &QTextBrowser::anchorClicked, this, [=](const QUrl &url){ + openUrl(url); + }); connect(_worldModel->selectionModel(), &QItemSelectionModel::currentChanged, this, &InfoBrowser::worldCurrentChanged); syncSelection(); } void InfoBrowser::showEvent(QShowEvent* event) { QDockWidget::showEvent(event); if(_selectionChanged) { _selectionChanged = false; QModelIndex current = _worldModel->selectionModel()->currentIndex(); worldCurrentChanged(current, QModelIndex()); } } void InfoBrowser::worldCurrentChanged(const QModelIndex& /*current*/, const QModelIndex& /*previous*/) { if(isVisible()) { if(_followAction->isChecked()) syncSelection(); else updateSyncSelection(); } else { _selectionChanged = true; } } void InfoBrowser::syncSelection(bool checked) { if(checked) { const QModelIndex current = _worldModel->selectionModel()->currentIndex(); const QUrl url(QStringLiteral("objinfo:").append(current.data(WorldModel::ClassNameRole).toString())); openUrl(url, true); } } void InfoBrowser::updateSyncSelection() { - if(_htmlPart->url().scheme() == QLatin1String("objinfo")) { + if(_htmlBrowser->source().scheme() == QLatin1String("objinfo")) { QModelIndex current = _worldModel->selectionModel()->currentIndex(); - if(_htmlPart->url().path() == current.data(WorldModel::ClassNameRole).toString()) { + if(_htmlBrowser->source().path() == current.data(WorldModel::ClassNameRole).toString()) { _syncAction->setEnabled(false); return; } } _syncAction->setEnabled(true); } void InfoBrowser::openUrl(const QUrl& url, bool clearHistory, bool fromHistory) { - // Cancel the old job - if(_wikiJob) _wikiJob->kill(); - _wikiJob = NULL; - - if(clearHistory) { - _forwardHistory.clear(); - _forwardAction->setEnabled(false); - _backHistory.clear(); - _backAction->setEnabled(false); - fromHistory = true; - } - if(url.scheme() == QLatin1String("objinfo")) { + if(clearHistory) { + _forwardHistory.clear(); + _forwardAction->setEnabled(false); + _backHistory.clear(); + _backAction->setEnabled(false); + fromHistory = true; + } QString className = url.path(); if(className.isEmpty()) { setHtml("" "\n" "
    \n" "
    \n" "\n" + i18n( "Documentation" ) + "\n" "
    \n" "
    \n" "

    \n" + i18n("No current object.") + "

    \n" "
    \n" "
    \n" "", fromHistory, url ); return; } - QString fileName = QStandardPaths::locate(QStandardPaths::DataLocation, QStringLiteral("objinfo/%1.html").arg(className)); + QString fileName = QStringLiteral(":/objectinfo/%1.html").arg(className.toLower()); if(!fileName.isEmpty()) { QFile file(fileName); if(file.open(QIODevice::ReadOnly | QIODevice::Text)) { - setHtml(QString::fromUtf8(file.readAll()), fromHistory, url /*QUrl::fromLocalFile(fileName)*/); + setHtml(QString::fromUtf8(file.readAll()), fromHistory, url); return; + } else { + qWarning() << "Could not open help file at location:" << fileName; } } setHtml("" "\n" "
    \n" "
    \n" "\n" + i18n( "Documentation error" ) + "\n" "
    \n" "
    \n" "

    \n" + i18n("Documentation for %1 not available. ", QCoreApplication::translate("ObjectClass", className.toUtf8().constData())) + i18n("You can help Step by writing it!") + "

    \n" "
    \n" "
    \n" "", fromHistory, url ); - return; - } else if(url.scheme() == QLatin1String("http")) { - if(!Settings::wikiExternal() && - QRegExp("[a-zA-Z-]+\\.wikipedia\\.org").exactMatch(url.host())) { - setHtml( - "" - "\n" - "
    \n" - "
    \n" - "\n" - + i18n( "Wikipedia" ) + - "\n" - "
    \n" - "
    \n" - "

    \n" + i18n( "Fetching Wikipedia Information..." ) + "

    \n" - "
    \n" - "
    \n" - "\n", fromHistory); - - _wikiUrl = url; - _wikiFromHistory = fromHistory; - _wikiJob = KIO::storedGet(url, KIO::NoReload, KIO::HideProgressInfo); - connect(_wikiJob, &KJob::result, this, &InfoBrowser::wikiResult); - } else { - QDesktopServices::openUrl(url); - } + show(); + } else if(url.scheme() == QLatin1String("https") || url.scheme() == QLatin1String("http")) { + // do not clear history when open external URL + QDesktopServices::openUrl(url); + } else { + qWarning() << "Unknown URL scheme detected, skipping:" << url; } - - show(); } void InfoBrowser::setHtml(const QString& data, bool fromHistory, const QUrl& url) { if(!fromHistory) { _forwardAction->setEnabled(false); _forwardHistory.clear(); - QString oldUrl = _htmlPart->url().url(); + QString oldUrl = _htmlBrowser->source().url(); if(!oldUrl.isEmpty()) { _backHistory << oldUrl; _backAction->setEnabled(true); } } - if(url.scheme() == QLatin1String("http")) _execAction->setEnabled(true); - else _execAction->setEnabled(false); + if(url.scheme() == QLatin1String("http")) { + _execAction->setEnabled(true); + } + else { + _execAction->setEnabled(false); + } + + _htmlBrowser->setSource(url); + _htmlBrowser->setHtml(data); - _htmlPart->begin(url); - _htmlPart->write( data ); - _htmlPart->end(); - updateSyncSelection(); } void InfoBrowser::back() { Q_ASSERT(!_backHistory.isEmpty()); QString url(_backHistory.takeLast()); if(_backHistory.isEmpty()) _backAction->setEnabled(false); - QString curUrl = _htmlPart->url().url(); + QString curUrl = _htmlBrowser->source().url(); if(!curUrl.isEmpty()) { _forwardHistory << curUrl; _forwardAction->setEnabled(true); } openUrl(QUrl(url), false, true); } void InfoBrowser::forward() { Q_ASSERT(!_forwardHistory.isEmpty()); QString url(_forwardHistory.takeLast()); if(_forwardHistory.isEmpty()) _forwardAction->setEnabled(false); - QString curUrl = _htmlPart->url().url(); + QString curUrl = _htmlBrowser->source().url(); if(!curUrl.isEmpty()) { _backHistory << curUrl; _backAction->setEnabled(true); } openUrl(QUrl(url), false, true); } void InfoBrowser::openInBrowser() { - if(_htmlPart->url().scheme() == QLatin1String("http")) { - QDesktopServices::openUrl(_htmlPart->url()); - } -} - -void InfoBrowser::wikiResult(KJob* job) -{ - // inspired by amarok - - if(job != _wikiJob) return; - - if(job->error() != 0) - { - setHtml("" - "\n" - "
    \n" - "
    \n" - "\n" - + i18n( "Wikipedia error" ) + - "\n" - "
    \n" - "
    \n

    \n" - + i18n( "Information could not be retrieved because the server was not reachable." ) + - "

    \n
    \n" - "
    \n" - "\n", _wikiFromHistory); - - return; + if(_htmlBrowser->source().scheme() == QLatin1String("https")) { + QDesktopServices::openUrl(_htmlBrowser->source()); } - - KIO::StoredTransferJob* const storedJob = static_cast( job ); - QByteArray rawData = storedJob->data(); - QString data; - - // TODO: better regexp - if(rawData.contains("charset=utf-8")) data = QString::fromUtf8(rawData.data()); - else data = QString(rawData); - - //if(data.find( "var wgArticleId = 0" ) != -1) // - article not found - - // remove the new-lines and tabs - data.replace( '\n', ' ' ); - data.replace( '\t', ' ' ); - - QString wikiLanguages; - // Get the available language list - if ( data.indexOf(QLatin1String("
    ")) != -1 ) - { - wikiLanguages = data.mid( data.indexOf(QLatin1String("
    ")) ); - wikiLanguages = wikiLanguages.mid( wikiLanguages.indexOf(QLatin1String("
      ")) ); - wikiLanguages = wikiLanguages.mid( 0, wikiLanguages.indexOf( QLatin1String("
    ") ) ); - } - - QString copyright; - QString copyrightMark = QStringLiteral("
  • "); - if ( data.indexOf( copyrightMark ) != -1 ) - { - copyright = data.mid( data.indexOf(copyrightMark) + copyrightMark.length() ); - copyright = copyright.mid( 0, copyright.indexOf( QLatin1String("
  • ") ) ); - copyright.remove( QStringLiteral("
    ") ); - //only one br at the beginning - copyright.prepend( "
    " ); - } - - // Ok lets remove the top and bottom parts of the page - data = data.mid( data.indexOf( QLatin1String("

    ") ) ); - data = data.mid( 0, data.indexOf( QLatin1String("
    ") ) ); - - // Adding back license information - data += copyright; - data.append( "
    " ); - - // Remove unnecessary sections (do it with style?) - data.remove( QRegExp("

    [^<]*

    ") ); - - data.remove( QRegExp( "]*>[^<]*<[^>]*>[^<]*<[^>]*>[^<]*" ) ); - - data.replace( QRegExp( "]*>([^<]*)" ), "\\1" ); - - // Remove anything inside of a class called urlexpansion, as it's pointless for us - data.remove( QRegExp( "[^(]*[(][^)]*[)]ttp inthttp" ) ); - - // Remove hidden table rows as well - QRegExp hidden( ".*", Qt::CaseInsensitive ); - hidden.setMinimal( true ); //greedy behavior wouldn't be any good! - data.remove( hidden ); - - // Remove jump-to-nav - QRegExp jumpToNav( "
    .*
    ", Qt::CaseInsensitive ); - jumpToNav.setMinimal( true ); - data.remove( jumpToNav ); - - // we want to keep our own style (we need to modify the stylesheet a bit to handle things nicely) - //data.remove( QRegExp( "style= *\"[^\"]*\"" ) ); - //data.remove( QRegExp( "class= *\"[^\"]*\"" ) ); - - // let's remove the form elements, we don't want them. - data.remove( QRegExp( "]*>" ) ); - data.remove( QRegExp( "]*>" ) ); - data.remove( QStringLiteral("\n") ); - data.remove( QRegExp( "]*>" ) ); - data.remove( QStringLiteral("\n") ); - data.remove( QRegExp( "]*>" ) ); - data.remove( QStringLiteral("") ); - - //first we convert all the links with protocol to external, as they should all be External Links. - //data.replace( QRegExp( "href= *\"http:" ), "href=\"externalurl:" ); - //QString url = _wikiUrl.url(); - //QString baseUrl = url.mid(0, url.indexOf("wiki/")); - //data.replace( QRegExp( "href= *\"/" ), "href=\"" + baseUrl ); - //data.replace( QRegExp( "href= *\"#" ), "href=\"" + baseUrl + '#' ); - - data.prepend("\n" - "
    \n" - "
    \n" - "\n" - + i18n( "Wikipedia Information" ) + - "\n" - "
    \n" - "
    \n"); - data.append( "
    \n" - "
    \n"); - - if (!wikiLanguages.isEmpty()) { - data.append( - "
    " - "
    \n" - "
    \n" - "\n" - + i18n( "Wikipedia Other Languages" ) + - "\n" - "
    \n" - "
    \n" - + wikiLanguages + - "
    \n" - "
    \n" - ); - } - data.append( "\n" ); - - setHtml( data, _wikiFromHistory, _wikiUrl ); - - _wikiJob = NULL; } - diff --git a/step/infobrowser.h b/step/infobrowser.h index e5e517b..ebea800 100644 --- a/step/infobrowser.h +++ b/step/infobrowser.h @@ -1,80 +1,76 @@ /* This file is part of Step. Copyright (C) 2007 Vladimir Kuznetsov Step is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Step is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Step; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef STEP_INFOBROWSER_H #define STEP_INFOBROWSER_H #include +#include #include class WorldModel; class QModelIndex; class QShowEvent; class QAction; class QUrl; class KToolBar; class KHTMLPart; class KJob; class InfoBrowser: public QDockWidget { Q_OBJECT public: - explicit InfoBrowser(WorldModel* worldModel, QWidget* parent = 0); + explicit InfoBrowser(WorldModel* worldModel, QWidget* parent = nullptr); public slots: void openUrl(const QUrl& url, bool clearHistory = false, bool fromHistory = false); protected slots: void worldCurrentChanged(const QModelIndex& current, const QModelIndex& previous); void setHtml(const QString& data, bool fromHistory = false, const QUrl& url = QUrl()); - void wikiResult(KJob* job); void back(); void forward(); void openInBrowser(); void syncSelection(bool checked = true); protected: void showEvent(QShowEvent* event) Q_DECL_OVERRIDE; void updateSyncSelection(); WorldModel* _worldModel; KToolBar* _toolBar; - KHTMLPart* _htmlPart; - - KJob* _wikiJob; - QUrl _wikiUrl; - bool _wikiFromHistory; + QTextBrowser* _htmlBrowser; QAction* _followAction; QAction* _syncAction; QAction* _execAction; QAction* _backAction; QAction* _forwardAction; QStringList _backHistory; QStringList _forwardHistory; bool _selectionChanged; }; #endif