mirror of
https://github.com/OpenMW/openmw.git
synced 2025-02-05 20:15:33 +00:00
Merge branch 'master' of https://github.com/OpenMW/openmw
This commit is contained in:
commit
7964d269ec
456 changed files with 12021 additions and 3736 deletions
|
@ -19,7 +19,6 @@ after_script:
|
||||||
- if [ "${TRAVIS_OS_NAME}" = "linux" ]; then ./openmw_test_suite; fi
|
- if [ "${TRAVIS_OS_NAME}" = "linux" ]; then ./openmw_test_suite; fi
|
||||||
notifications:
|
notifications:
|
||||||
recipients:
|
recipients:
|
||||||
- lgromanowski+travis.ci@gmail.com
|
|
||||||
- corrmage+travis-ci@gmail.com
|
- corrmage+travis-ci@gmail.com
|
||||||
email:
|
email:
|
||||||
on_success: change
|
on_success: change
|
||||||
|
|
|
@ -6,4 +6,4 @@ export CC=clang
|
||||||
brew tap openmw/openmw
|
brew tap openmw/openmw
|
||||||
brew update
|
brew update
|
||||||
brew unlink boost
|
brew unlink boost
|
||||||
brew install cmake openmw-mygui openmw-bullet openmw-sdl2 openmw-ffmpeg pkg-config qt unshield
|
brew install openmw-mygui openmw-bullet openmw-sdl2 openmw-ffmpeg qt unshield
|
||||||
|
|
|
@ -12,7 +12,7 @@ set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/)
|
||||||
message(STATUS "Configuring OpenMW...")
|
message(STATUS "Configuring OpenMW...")
|
||||||
|
|
||||||
set(OPENMW_VERSION_MAJOR 0)
|
set(OPENMW_VERSION_MAJOR 0)
|
||||||
set(OPENMW_VERSION_MINOR 33)
|
set(OPENMW_VERSION_MINOR 34)
|
||||||
set(OPENMW_VERSION_RELEASE 0)
|
set(OPENMW_VERSION_RELEASE 0)
|
||||||
|
|
||||||
set(OPENMW_VERSION_COMMITHASH "")
|
set(OPENMW_VERSION_COMMITHASH "")
|
||||||
|
@ -25,24 +25,28 @@ if(EXISTS ${PROJECT_SOURCE_DIR}/.git)
|
||||||
find_package(Git)
|
find_package(Git)
|
||||||
|
|
||||||
if(GIT_FOUND)
|
if(GIT_FOUND)
|
||||||
include(GetGitRevisionDescription)
|
execute_process (
|
||||||
get_git_tag_revision(TAGHASH --tags --max-count=1)
|
COMMAND "${GIT_EXECUTABLE}" rev-list --tags --max-count=1
|
||||||
get_git_head_revision(REFSPEC COMMITHASH)
|
WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}"
|
||||||
git_describe(VERSION --tags ${TAGHASH})
|
RESULT_VARIABLE EXITCODE1
|
||||||
|
OUTPUT_VARIABLE TAGHASH
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||||
|
|
||||||
string(REGEX MATCH "^openmw-[^0-9]*[0-9]+\\.[0-9]+\\.[0-9]+.*" MATCH "${VERSION}")
|
execute_process (
|
||||||
if(MATCH)
|
COMMAND "${GIT_EXECUTABLE}" rev-parse HEAD
|
||||||
string(REGEX REPLACE "^openmw-([0-9]+)\\..*" "\\1" GIT_VERSION_MAJOR "${VERSION}")
|
WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}"
|
||||||
string(REGEX REPLACE "^openmw-[0-9]+\\.([0-9]+).*" "\\1" GIT_VERSION_MINOR "${VERSION}")
|
RESULT_VARIABLE EXITCODE2
|
||||||
string(REGEX REPLACE "^openmw-[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" GIT_VERSION_RELEASE "${VERSION}")
|
OUTPUT_VARIABLE COMMITHASH
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||||
|
|
||||||
|
string (COMPARE EQUAL "${EXITCODE1}:${EXITCODE2}" "0:0" SUCCESS)
|
||||||
|
if (SUCCESS)
|
||||||
set(OPENMW_VERSION_COMMITHASH "${COMMITHASH}")
|
set(OPENMW_VERSION_COMMITHASH "${COMMITHASH}")
|
||||||
set(OPENMW_VERSION_TAGHASH "${TAGHASH}")
|
set(OPENMW_VERSION_TAGHASH "${TAGHASH}")
|
||||||
|
|
||||||
message(STATUS "OpenMW version ${OPENMW_VERSION}")
|
message(STATUS "OpenMW version ${OPENMW_VERSION}")
|
||||||
else(MATCH)
|
else (SUCCESS)
|
||||||
message(WARNING "Failed to get valid version information from Git")
|
message(WARNING "Failed to get valid version information from Git")
|
||||||
endif(MATCH)
|
endif (SUCCESS)
|
||||||
else(GIT_FOUND)
|
else(GIT_FOUND)
|
||||||
message(WARNING "Git executable not found")
|
message(WARNING "Git executable not found")
|
||||||
endif(GIT_FOUND)
|
endif(GIT_FOUND)
|
||||||
|
@ -75,6 +79,7 @@ option(BUILD_ESMTOOL "build ESM inspector" ON)
|
||||||
option(BUILD_LAUNCHER "build Launcher" ON)
|
option(BUILD_LAUNCHER "build Launcher" ON)
|
||||||
option(BUILD_MWINIIMPORTER "build MWiniImporter" ON)
|
option(BUILD_MWINIIMPORTER "build MWiniImporter" ON)
|
||||||
option(BUILD_OPENCS "build OpenMW Construction Set" ON)
|
option(BUILD_OPENCS "build OpenMW Construction Set" ON)
|
||||||
|
option(BUILD_WIZARD "build Installation Wizard" ON)
|
||||||
option(BUILD_WITH_CODE_COVERAGE "Enable code coverage with gconv" OFF)
|
option(BUILD_WITH_CODE_COVERAGE "Enable code coverage with gconv" OFF)
|
||||||
option(BUILD_UNITTESTS "Enable Unittests with Google C++ Unittest and GMock frameworks" OFF)
|
option(BUILD_UNITTESTS "Enable Unittests with Google C++ Unittest and GMock frameworks" OFF)
|
||||||
option(BUILD_NIFTEST "build nif file tester" OFF)
|
option(BUILD_NIFTEST "build nif file tester" OFF)
|
||||||
|
@ -433,6 +438,9 @@ IF(NOT WIN32 AND NOT APPLE)
|
||||||
IF(BUILD_NIFTEST)
|
IF(BUILD_NIFTEST)
|
||||||
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/niftest" DESTINATION "${BINDIR}" )
|
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/niftest" DESTINATION "${BINDIR}" )
|
||||||
ENDIF(BUILD_NIFTEST)
|
ENDIF(BUILD_NIFTEST)
|
||||||
|
IF(BUILD_WIZARD)
|
||||||
|
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/openmw-wizard" DESTINATION "${BINDIR}" )
|
||||||
|
ENDIF(BUILD_WIZARD)
|
||||||
if(BUILD_MYGUI_PLUGIN)
|
if(BUILD_MYGUI_PLUGIN)
|
||||||
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Plugin_MyGUI_OpenMW_Resources.so" DESTINATION "${LIBDIR}" )
|
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Plugin_MyGUI_OpenMW_Resources.so" DESTINATION "${LIBDIR}" )
|
||||||
ENDIF(BUILD_MYGUI_PLUGIN)
|
ENDIF(BUILD_MYGUI_PLUGIN)
|
||||||
|
@ -485,6 +493,9 @@ if(WIN32)
|
||||||
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Release/opencs.exe" DESTINATION ".")
|
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Release/opencs.exe" DESTINATION ".")
|
||||||
INSTALL(FILES "${OpenMW_BINARY_DIR}/opencs.ini" DESTINATION ".")
|
INSTALL(FILES "${OpenMW_BINARY_DIR}/opencs.ini" DESTINATION ".")
|
||||||
ENDIF(BUILD_OPENCS)
|
ENDIF(BUILD_OPENCS)
|
||||||
|
IF(BUILD_WIZARD)
|
||||||
|
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Release/openmw-wizard.exe" DESTINATION ".")
|
||||||
|
ENDIF(BUILD_WIZARD)
|
||||||
if(BUILD_MYGUI_PLUGIN)
|
if(BUILD_MYGUI_PLUGIN)
|
||||||
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Release/Plugin_MyGUI_OpenMW_Resources.dll" DESTINATION ".")
|
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Release/Plugin_MyGUI_OpenMW_Resources.dll" DESTINATION ".")
|
||||||
ENDIF(BUILD_MYGUI_PLUGIN)
|
ENDIF(BUILD_MYGUI_PLUGIN)
|
||||||
|
@ -505,6 +516,9 @@ if(WIN32)
|
||||||
IF(BUILD_OPENCS)
|
IF(BUILD_OPENCS)
|
||||||
SET(CPACK_PACKAGE_EXECUTABLES "${CPACK_PACKAGE_EXECUTABLES};opencs;OpenMW Construction Set")
|
SET(CPACK_PACKAGE_EXECUTABLES "${CPACK_PACKAGE_EXECUTABLES};opencs;OpenMW Construction Set")
|
||||||
ENDIF(BUILD_OPENCS)
|
ENDIF(BUILD_OPENCS)
|
||||||
|
IF(BUILD_WIZARD)
|
||||||
|
SET(CPACK_PACKAGE_EXECUTABLES "${CPACK_PACKAGE_EXECUTABLES};openmw-wizard;OpenMW Wizard")
|
||||||
|
ENDIF(BUILD_WIZARD)
|
||||||
SET(CPACK_NSIS_CREATE_ICONS_EXTRA "CreateShortCut '\$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\Readme.lnk' '\$INSTDIR\\\\readme.txt'")
|
SET(CPACK_NSIS_CREATE_ICONS_EXTRA "CreateShortCut '\$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\Readme.lnk' '\$INSTDIR\\\\readme.txt'")
|
||||||
SET(CPACK_NSIS_DELETE_ICONS_EXTRA "
|
SET(CPACK_NSIS_DELETE_ICONS_EXTRA "
|
||||||
!insertmacro MUI_STARTMENU_GETFOLDER Application $MUI_TEMP
|
!insertmacro MUI_STARTMENU_GETFOLDER Application $MUI_TEMP
|
||||||
|
@ -578,13 +592,6 @@ if (BUILD_ESMTOOL)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (BUILD_LAUNCHER)
|
if (BUILD_LAUNCHER)
|
||||||
if(NOT WIN32)
|
|
||||||
find_package(LIBUNSHIELD REQUIRED)
|
|
||||||
if(NOT LIBUNSHIELD_FOUND)
|
|
||||||
message(SEND_ERROR "Failed to find libunshield")
|
|
||||||
endif(NOT LIBUNSHIELD_FOUND)
|
|
||||||
endif(NOT WIN32)
|
|
||||||
|
|
||||||
add_subdirectory( apps/launcher )
|
add_subdirectory( apps/launcher )
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
@ -596,6 +603,10 @@ if (BUILD_OPENCS)
|
||||||
add_subdirectory (apps/opencs)
|
add_subdirectory (apps/opencs)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (BUILD_WIZARD)
|
||||||
|
add_subdirectory(apps/wizard)
|
||||||
|
endif()
|
||||||
|
|
||||||
# UnitTests
|
# UnitTests
|
||||||
if (BUILD_UNITTESTS)
|
if (BUILD_UNITTESTS)
|
||||||
add_subdirectory( apps/openmw_test_suite )
|
add_subdirectory( apps/openmw_test_suite )
|
||||||
|
@ -698,6 +709,9 @@ if (WIN32)
|
||||||
if (BUILD_ESMTOOL)
|
if (BUILD_ESMTOOL)
|
||||||
set_target_properties(esmtool PROPERTIES COMPILE_FLAGS "${WARNINGS} ${MT_BUILD}")
|
set_target_properties(esmtool PROPERTIES COMPILE_FLAGS "${WARNINGS} ${MT_BUILD}")
|
||||||
endif (BUILD_ESMTOOL)
|
endif (BUILD_ESMTOOL)
|
||||||
|
if (BUILD_WIZARD)
|
||||||
|
set_target_properties(openmw-wizard PROPERTIES COMPILE_FLAGS ${WARNINGS})
|
||||||
|
endif (BUILD_WIZARD)
|
||||||
if (BUILD_OPENCS)
|
if (BUILD_OPENCS)
|
||||||
# QT triggers an informational warning that the object layout may differ when compiled with /vd2
|
# QT triggers an informational warning that the object layout may differ when compiled with /vd2
|
||||||
set(OPENCS_WARNINGS "${WARNINGS} ${MT_BUILD} /wd4435")
|
set(OPENCS_WARNINGS "${WARNINGS} ${MT_BUILD} /wd4435")
|
||||||
|
|
|
@ -51,7 +51,7 @@ bool parseOptions (int argc, char** argv, Arguments &info)
|
||||||
("help,h", "print help message.")
|
("help,h", "print help message.")
|
||||||
("version,v", "print version information and quit.")
|
("version,v", "print version information and quit.")
|
||||||
("long,l", "Include extra information in archive listing.")
|
("long,l", "Include extra information in archive listing.")
|
||||||
("full-path,f", "Create diretory hierarchy on file extraction "
|
("full-path,f", "Create directory hierarchy on file extraction "
|
||||||
"(always true for extractall).")
|
"(always true for extractall).")
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
|
@ -5,21 +5,16 @@ set(LAUNCHER
|
||||||
maindialog.cpp
|
maindialog.cpp
|
||||||
playpage.cpp
|
playpage.cpp
|
||||||
textslotmsgbox.cpp
|
textslotmsgbox.cpp
|
||||||
|
settingspage.cpp
|
||||||
|
|
||||||
settings/gamesettings.cpp
|
|
||||||
settings/graphicssettings.cpp
|
settings/graphicssettings.cpp
|
||||||
settings/launchersettings.cpp
|
|
||||||
|
|
||||||
utils/checkablemessagebox.cpp
|
|
||||||
utils/profilescombobox.cpp
|
utils/profilescombobox.cpp
|
||||||
utils/textinputdialog.cpp
|
utils/textinputdialog.cpp
|
||||||
utils/lineedit.cpp
|
utils/lineedit.cpp
|
||||||
|
|
||||||
${CMAKE_SOURCE_DIR}/files/windows/launcher.rc
|
${CMAKE_SOURCE_DIR}/files/windows/launcher.rc
|
||||||
)
|
)
|
||||||
if(NOT WIN32)
|
|
||||||
LIST(APPEND LAUNCHER unshieldthread.cpp)
|
|
||||||
endif(NOT WIN32)
|
|
||||||
|
|
||||||
set(LAUNCHER_HEADER
|
set(LAUNCHER_HEADER
|
||||||
datafilespage.hpp
|
datafilespage.hpp
|
||||||
|
@ -27,21 +22,14 @@ set(LAUNCHER_HEADER
|
||||||
maindialog.hpp
|
maindialog.hpp
|
||||||
playpage.hpp
|
playpage.hpp
|
||||||
textslotmsgbox.hpp
|
textslotmsgbox.hpp
|
||||||
|
settingspage.hpp
|
||||||
|
|
||||||
settings/gamesettings.hpp
|
|
||||||
settings/graphicssettings.hpp
|
settings/graphicssettings.hpp
|
||||||
settings/launchersettings.hpp
|
|
||||||
settings/settingsbase.hpp
|
|
||||||
|
|
||||||
utils/checkablemessagebox.hpp
|
|
||||||
utils/profilescombobox.hpp
|
utils/profilescombobox.hpp
|
||||||
utils/textinputdialog.hpp
|
utils/textinputdialog.hpp
|
||||||
utils/lineedit.hpp
|
utils/lineedit.hpp
|
||||||
)
|
)
|
||||||
if(NOT WIN32)
|
|
||||||
LIST(APPEND LAUNCHER_HEADER unshieldthread.hpp)
|
|
||||||
endif(NOT WIN32)
|
|
||||||
|
|
||||||
|
|
||||||
# Headers that must be pre-processed
|
# Headers that must be pre-processed
|
||||||
set(LAUNCHER_HEADER_MOC
|
set(LAUNCHER_HEADER_MOC
|
||||||
|
@ -50,25 +38,21 @@ set(LAUNCHER_HEADER_MOC
|
||||||
maindialog.hpp
|
maindialog.hpp
|
||||||
playpage.hpp
|
playpage.hpp
|
||||||
textslotmsgbox.hpp
|
textslotmsgbox.hpp
|
||||||
|
settingspage.hpp
|
||||||
|
|
||||||
utils/textinputdialog.hpp
|
utils/textinputdialog.hpp
|
||||||
utils/checkablemessagebox.hpp
|
|
||||||
utils/profilescombobox.hpp
|
utils/profilescombobox.hpp
|
||||||
utils/lineedit.hpp
|
utils/lineedit.hpp
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if(NOT WIN32)
|
|
||||||
LIST(APPEND LAUNCHER_HEADER_MOC unshieldthread.hpp)
|
|
||||||
endif(NOT WIN32)
|
|
||||||
|
|
||||||
|
|
||||||
set(LAUNCHER_UI
|
set(LAUNCHER_UI
|
||||||
${CMAKE_SOURCE_DIR}/files/ui/datafilespage.ui
|
${CMAKE_SOURCE_DIR}/files/ui/datafilespage.ui
|
||||||
${CMAKE_SOURCE_DIR}/files/ui/graphicspage.ui
|
${CMAKE_SOURCE_DIR}/files/ui/graphicspage.ui
|
||||||
${CMAKE_SOURCE_DIR}/files/ui/mainwindow.ui
|
${CMAKE_SOURCE_DIR}/files/ui/mainwindow.ui
|
||||||
${CMAKE_SOURCE_DIR}/files/ui/playpage.ui
|
${CMAKE_SOURCE_DIR}/files/ui/playpage.ui
|
||||||
${CMAKE_SOURCE_DIR}/files/ui/contentselector.ui
|
${CMAKE_SOURCE_DIR}/files/ui/contentselector.ui
|
||||||
|
${CMAKE_SOURCE_DIR}/files/ui/settingspage.ui
|
||||||
)
|
)
|
||||||
|
|
||||||
source_group(launcher FILES ${LAUNCHER} ${LAUNCHER_HEADER})
|
source_group(launcher FILES ${LAUNCHER} ${LAUNCHER_HEADER})
|
||||||
|
@ -111,12 +95,6 @@ target_link_libraries(omwlauncher
|
||||||
${QT_LIBRARIES}
|
${QT_LIBRARIES}
|
||||||
components
|
components
|
||||||
)
|
)
|
||||||
if(NOT WIN32)
|
|
||||||
target_link_libraries(omwlauncher
|
|
||||||
${LIBUNSHIELD_LIBRARY}
|
|
||||||
)
|
|
||||||
endif(NOT WIN32)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (BUILD_WITH_CODE_COVERAGE)
|
if (BUILD_WITH_CODE_COVERAGE)
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#include "datafilespage.hpp"
|
#include "datafilespage.hpp"
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QCheckBox>
|
#include <QCheckBox>
|
||||||
|
@ -9,18 +11,16 @@
|
||||||
#include <components/files/configurationmanager.hpp>
|
#include <components/files/configurationmanager.hpp>
|
||||||
|
|
||||||
#include <components/contentselector/model/esmfile.hpp>
|
#include <components/contentselector/model/esmfile.hpp>
|
||||||
|
|
||||||
#include <components/contentselector/model/naturalsort.hpp>
|
#include <components/contentselector/model/naturalsort.hpp>
|
||||||
|
#include <components/contentselector/view/contentselector.hpp>
|
||||||
|
|
||||||
|
#include <components/config/gamesettings.hpp>
|
||||||
|
#include <components/config/launchersettings.hpp>
|
||||||
|
|
||||||
#include "utils/textinputdialog.hpp"
|
#include "utils/textinputdialog.hpp"
|
||||||
#include "utils/profilescombobox.hpp"
|
#include "utils/profilescombobox.hpp"
|
||||||
|
|
||||||
#include "settings/gamesettings.hpp"
|
Launcher::DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, Config::GameSettings &gameSettings, Config::LauncherSettings &launcherSettings, QWidget *parent)
|
||||||
#include "settings/launchersettings.hpp"
|
|
||||||
|
|
||||||
#include "components/contentselector/view/contentselector.hpp"
|
|
||||||
|
|
||||||
Launcher::DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, GameSettings &gameSettings, LauncherSettings &launcherSettings, QWidget *parent)
|
|
||||||
: mCfgMgr(cfg)
|
: mCfgMgr(cfg)
|
||||||
, mGameSettings(gameSettings)
|
, mGameSettings(gameSettings)
|
||||||
, mLauncherSettings(launcherSettings)
|
, mLauncherSettings(launcherSettings)
|
||||||
|
@ -30,20 +30,71 @@ Launcher::DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, GameSet
|
||||||
setObjectName ("DataFilesPage");
|
setObjectName ("DataFilesPage");
|
||||||
mSelector = new ContentSelectorView::ContentSelector (ui.contentSelectorWidget);
|
mSelector = new ContentSelectorView::ContentSelector (ui.contentSelectorWidget);
|
||||||
|
|
||||||
|
mProfileDialog = new TextInputDialog(tr("New Profile"), tr("Profile name:"), this);
|
||||||
|
|
||||||
|
connect(mProfileDialog->lineEdit(), SIGNAL(textChanged(QString)),
|
||||||
|
this, SLOT(updateOkButton(QString)));
|
||||||
|
|
||||||
buildView();
|
buildView();
|
||||||
setupDataFiles();
|
loadSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Launcher::DataFilesPage::loadSettings()
|
void Launcher::DataFilesPage::buildView()
|
||||||
|
{
|
||||||
|
ui.verticalLayout->insertWidget (0, mSelector->uiWidget());
|
||||||
|
|
||||||
|
//tool buttons
|
||||||
|
ui.newProfileButton->setToolTip ("Create a new profile");
|
||||||
|
ui.deleteProfileButton->setToolTip ("Delete an existing profile");
|
||||||
|
|
||||||
|
//combo box
|
||||||
|
ui.profilesComboBox->addItem ("Default");
|
||||||
|
ui.profilesComboBox->setPlaceholderText (QString("Select a profile..."));
|
||||||
|
ui.profilesComboBox->setCurrentIndex(ui.profilesComboBox->findText(QLatin1String("Default")));
|
||||||
|
|
||||||
|
// Add the actions to the toolbuttons
|
||||||
|
ui.newProfileButton->setDefaultAction (ui.newProfileAction);
|
||||||
|
ui.deleteProfileButton->setDefaultAction (ui.deleteProfileAction);
|
||||||
|
|
||||||
|
//establish connections
|
||||||
|
connect (ui.profilesComboBox, SIGNAL (currentIndexChanged(int)),
|
||||||
|
this, SLOT (slotProfileChanged(int)));
|
||||||
|
|
||||||
|
connect (ui.profilesComboBox, SIGNAL (profileRenamed(QString, QString)),
|
||||||
|
this, SLOT (slotProfileRenamed(QString, QString)));
|
||||||
|
|
||||||
|
connect (ui.profilesComboBox, SIGNAL (signalProfileChanged(QString, QString)),
|
||||||
|
this, SLOT (slotProfileChangedByUser(QString, QString)));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Launcher::DataFilesPage::loadSettings()
|
||||||
{
|
{
|
||||||
QStringList paths = mGameSettings.getDataDirs();
|
QStringList paths = mGameSettings.getDataDirs();
|
||||||
|
|
||||||
|
foreach (const QString &path, paths)
|
||||||
|
mSelector->addFiles(path);
|
||||||
|
|
||||||
|
mDataLocal = mGameSettings.getDataLocal();
|
||||||
|
|
||||||
|
if (!mDataLocal.isEmpty())
|
||||||
|
mSelector->addFiles(mDataLocal);
|
||||||
|
|
||||||
paths.insert (0, mDataLocal);
|
paths.insert (0, mDataLocal);
|
||||||
PathIterator pathIterator (paths);
|
PathIterator pathIterator (paths);
|
||||||
|
|
||||||
QString profileName = ui.profilesComboBox->currentText();
|
QStringList profiles = mLauncherSettings.subKeys(QString("Profiles/"));
|
||||||
|
QString currentProfile = mLauncherSettings.getSettings().value("Profiles/currentprofile");
|
||||||
|
|
||||||
QStringList files = mLauncherSettings.values(QString("Profiles/") + profileName, Qt::MatchExactly);
|
qDebug() << "current profile is: " << currentProfile;
|
||||||
|
|
||||||
|
foreach (const QString &item, profiles)
|
||||||
|
addProfile (item, false);
|
||||||
|
|
||||||
|
// Hack: also add the current profile
|
||||||
|
if (!currentProfile.isEmpty())
|
||||||
|
addProfile(currentProfile, true);
|
||||||
|
|
||||||
|
QStringList files = mLauncherSettings.values(QString("Profiles/") + currentProfile + QString("/content"), Qt::MatchExactly);
|
||||||
QStringList filepaths;
|
QStringList filepaths;
|
||||||
|
|
||||||
foreach (const QString &file, files)
|
foreach (const QString &file, files)
|
||||||
|
@ -55,6 +106,8 @@ void Launcher::DataFilesPage::loadSettings()
|
||||||
}
|
}
|
||||||
|
|
||||||
mSelector->setProfileContent (filepaths);
|
mSelector->setProfileContent (filepaths);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Launcher::DataFilesPage::saveSettings(const QString &profile)
|
void Launcher::DataFilesPage::saveSettings(const QString &profile)
|
||||||
|
@ -75,42 +128,16 @@ void Launcher::DataFilesPage::saveSettings(const QString &profile)
|
||||||
mLauncherSettings.setValue(QString("Profiles/currentprofile"), ui.profilesComboBox->currentText());
|
mLauncherSettings.setValue(QString("Profiles/currentprofile"), ui.profilesComboBox->currentText());
|
||||||
|
|
||||||
foreach(const ContentSelectorModel::EsmFile *item, items) {
|
foreach(const ContentSelectorModel::EsmFile *item, items) {
|
||||||
mLauncherSettings.setMultiValue(QString("Profiles/") + profileName, item->fileName());
|
mLauncherSettings.setMultiValue(QString("Profiles/") + profileName + QString("/content"), item->fileName());
|
||||||
mGameSettings.setMultiValue(QString("content"), item->fileName());
|
mGameSettings.setMultiValue(QString("content"), item->fileName());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Launcher::DataFilesPage::buildView()
|
|
||||||
{
|
|
||||||
ui.verticalLayout->insertWidget (0, mSelector->uiWidget());
|
|
||||||
|
|
||||||
//tool buttons
|
|
||||||
ui.newProfileButton->setToolTip ("Create a new profile");
|
|
||||||
ui.deleteProfileButton->setToolTip ("Delete an existing profile");
|
|
||||||
|
|
||||||
//combo box
|
|
||||||
ui.profilesComboBox->addItem ("Default");
|
|
||||||
ui.profilesComboBox->setPlaceholderText (QString("Select a profile..."));
|
|
||||||
|
|
||||||
// Add the actions to the toolbuttons
|
|
||||||
ui.newProfileButton->setDefaultAction (ui.newProfileAction);
|
|
||||||
ui.deleteProfileButton->setDefaultAction (ui.deleteProfileAction);
|
|
||||||
|
|
||||||
//establish connections
|
|
||||||
connect (ui.profilesComboBox, SIGNAL (currentIndexChanged(int)),
|
|
||||||
this, SLOT (slotProfileChanged(int)));
|
|
||||||
|
|
||||||
connect (ui.profilesComboBox, SIGNAL (profileRenamed(QString, QString)),
|
|
||||||
this, SLOT (slotProfileRenamed(QString, QString)));
|
|
||||||
|
|
||||||
connect (ui.profilesComboBox, SIGNAL (signalProfileChanged(QString, QString)),
|
|
||||||
this, SLOT (slotProfileChangedByUser(QString, QString)));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Launcher::DataFilesPage::removeProfile(const QString &profile)
|
void Launcher::DataFilesPage::removeProfile(const QString &profile)
|
||||||
{
|
{
|
||||||
mLauncherSettings.remove(QString("Profiles/") + profile);
|
mLauncherSettings.remove(QString("Profiles/") + profile);
|
||||||
|
mLauncherSettings.remove(QString("Profiles/") + profile + QString("/content"));
|
||||||
}
|
}
|
||||||
|
|
||||||
QAbstractItemModel *Launcher::DataFilesPage::profilesModel() const
|
QAbstractItemModel *Launcher::DataFilesPage::profilesModel() const
|
||||||
|
@ -127,9 +154,11 @@ void Launcher::DataFilesPage::setProfile(int index, bool savePrevious)
|
||||||
{
|
{
|
||||||
if (index >= -1 && index < ui.profilesComboBox->count())
|
if (index >= -1 && index < ui.profilesComboBox->count())
|
||||||
{
|
{
|
||||||
QString previous = ui.profilesComboBox->itemText(ui.profilesComboBox->currentIndex());
|
QString previous = mPreviousProfile;
|
||||||
QString current = ui.profilesComboBox->itemText(index);
|
QString current = ui.profilesComboBox->itemText(index);
|
||||||
|
|
||||||
|
mPreviousProfile = current;
|
||||||
|
|
||||||
setProfile (previous, current, savePrevious);
|
setProfile (previous, current, savePrevious);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -177,62 +206,29 @@ void Launcher::DataFilesPage::slotProfileRenamed(const QString &previous, const
|
||||||
|
|
||||||
void Launcher::DataFilesPage::slotProfileChanged(int index)
|
void Launcher::DataFilesPage::slotProfileChanged(int index)
|
||||||
{
|
{
|
||||||
|
// in case the event was triggered externally
|
||||||
|
if (ui.profilesComboBox->currentIndex() != index)
|
||||||
|
ui.profilesComboBox->setCurrentIndex(index);
|
||||||
|
|
||||||
setProfile (index, true);
|
setProfile (index, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Launcher::DataFilesPage::setupDataFiles()
|
|
||||||
{
|
|
||||||
QStringList paths = mGameSettings.getDataDirs();
|
|
||||||
|
|
||||||
foreach (const QString &path, paths)
|
|
||||||
mSelector->addFiles(path);
|
|
||||||
|
|
||||||
mDataLocal = mGameSettings.getDataLocal();
|
|
||||||
|
|
||||||
if (!mDataLocal.isEmpty())
|
|
||||||
mSelector->addFiles(mDataLocal);
|
|
||||||
|
|
||||||
QStringList profiles;
|
|
||||||
QString currentProfile = mLauncherSettings.getSettings().value("Profiles/currentprofile");
|
|
||||||
|
|
||||||
foreach (QString key, mLauncherSettings.getSettings().keys())
|
|
||||||
{
|
|
||||||
if (key.contains("Profiles/"))
|
|
||||||
{
|
|
||||||
QString profile = key.mid (9);
|
|
||||||
if (profile != "currentprofile")
|
|
||||||
{
|
|
||||||
if (!profiles.contains(profile))
|
|
||||||
profiles << profile;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (const QString &item, profiles)
|
|
||||||
addProfile (item, false);
|
|
||||||
|
|
||||||
setProfile (ui.profilesComboBox->findText(currentProfile), false);
|
|
||||||
|
|
||||||
loadSettings();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Launcher::DataFilesPage::on_newProfileAction_triggered()
|
void Launcher::DataFilesPage::on_newProfileAction_triggered()
|
||||||
{
|
{
|
||||||
TextInputDialog newDialog (tr("New Profile"), tr("Profile name:"), this);
|
if (mProfileDialog->exec() != QDialog::Accepted)
|
||||||
|
|
||||||
if (newDialog.exec() != QDialog::Accepted)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QString profile = newDialog.getText();
|
QString profile = mProfileDialog->lineEdit()->text();
|
||||||
|
|
||||||
if (profile.isEmpty())
|
if (profile.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
saveSettings();
|
saveSettings();
|
||||||
|
|
||||||
mSelector->clearCheckStates();
|
mLauncherSettings.setValue(QString("Profiles/currentprofile"), profile);
|
||||||
|
|
||||||
addProfile(profile, true);
|
addProfile(profile, true);
|
||||||
|
mSelector->clearCheckStates();
|
||||||
|
|
||||||
mSelector->setGameFile();
|
mSelector->setGameFile();
|
||||||
|
|
||||||
|
@ -246,9 +242,7 @@ void Launcher::DataFilesPage::addProfile (const QString &profile, bool setAsCurr
|
||||||
if (profile.isEmpty())
|
if (profile.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (ui.profilesComboBox->findText (profile) != -1)
|
if (ui.profilesComboBox->findText (profile) == -1)
|
||||||
return;
|
|
||||||
|
|
||||||
ui.profilesComboBox->addItem (profile);
|
ui.profilesComboBox->addItem (profile);
|
||||||
|
|
||||||
if (setAsCurrent)
|
if (setAsCurrent)
|
||||||
|
@ -265,10 +259,12 @@ void Launcher::DataFilesPage::on_deleteProfileAction_triggered()
|
||||||
if (!showDeleteMessageBox (profile))
|
if (!showDeleteMessageBox (profile))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Remove the profile from the combobox
|
// this should work since the Default profile can't be deleted and is always index 0
|
||||||
ui.profilesComboBox->removeItem (ui.profilesComboBox->findText (profile));
|
int next = ui.profilesComboBox->currentIndex()-1;
|
||||||
|
ui.profilesComboBox->setCurrentIndex(next);
|
||||||
|
|
||||||
removeProfile(profile);
|
removeProfile(profile);
|
||||||
|
ui.profilesComboBox->removeItem(ui.profilesComboBox->findText(profile));
|
||||||
|
|
||||||
saveSettings();
|
saveSettings();
|
||||||
|
|
||||||
|
@ -277,6 +273,19 @@ void Launcher::DataFilesPage::on_deleteProfileAction_triggered()
|
||||||
checkForDefaultProfile();
|
checkForDefaultProfile();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Launcher::DataFilesPage::updateOkButton(const QString &text)
|
||||||
|
{
|
||||||
|
// We do this here because we need the profiles combobox text
|
||||||
|
if (text.isEmpty()) {
|
||||||
|
mProfileDialog->setOkButtonEnabled(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
(ui.profilesComboBox->findText(text) == -1)
|
||||||
|
? mProfileDialog->setOkButtonEnabled(true)
|
||||||
|
: mProfileDialog->setOkButtonEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
void Launcher::DataFilesPage::checkForDefaultProfile()
|
void Launcher::DataFilesPage::checkForDefaultProfile()
|
||||||
{
|
{
|
||||||
//don't allow deleting "Default" profile
|
//don't allow deleting "Default" profile
|
||||||
|
|
|
@ -14,12 +14,12 @@ class QMenu;
|
||||||
|
|
||||||
namespace Files { struct ConfigurationManager; }
|
namespace Files { struct ConfigurationManager; }
|
||||||
namespace ContentSelectorView { class ContentSelector; }
|
namespace ContentSelectorView { class ContentSelector; }
|
||||||
|
namespace Config { class GameSettings;
|
||||||
|
class LauncherSettings; }
|
||||||
|
|
||||||
namespace Launcher
|
namespace Launcher
|
||||||
{
|
{
|
||||||
class TextInputDialog;
|
class TextInputDialog;
|
||||||
class GameSettings;
|
|
||||||
class LauncherSettings;
|
|
||||||
class ProfilesComboBox;
|
class ProfilesComboBox;
|
||||||
|
|
||||||
class DataFilesPage : public QWidget
|
class DataFilesPage : public QWidget
|
||||||
|
@ -30,8 +30,8 @@ namespace Launcher
|
||||||
Ui::DataFilesPage ui;
|
Ui::DataFilesPage ui;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit DataFilesPage (Files::ConfigurationManager &cfg, GameSettings &gameSettings,
|
explicit DataFilesPage (Files::ConfigurationManager &cfg, Config::GameSettings &gameSettings,
|
||||||
LauncherSettings &launcherSettings, QWidget *parent = 0);
|
Config::LauncherSettings &launcherSettings, QWidget *parent = 0);
|
||||||
|
|
||||||
QAbstractItemModel* profilesModel() const;
|
QAbstractItemModel* profilesModel() const;
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ namespace Launcher
|
||||||
|
|
||||||
//void writeConfig(QString profile = QString());
|
//void writeConfig(QString profile = QString());
|
||||||
void saveSettings(const QString &profile = "");
|
void saveSettings(const QString &profile = "");
|
||||||
void loadSettings();
|
bool loadSettings();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void signalProfileChanged (int index);
|
void signalProfileChanged (int index);
|
||||||
|
@ -53,24 +53,27 @@ namespace Launcher
|
||||||
void slotProfileRenamed(const QString &previous, const QString ¤t);
|
void slotProfileRenamed(const QString &previous, const QString ¤t);
|
||||||
void slotProfileDeleted(const QString &item);
|
void slotProfileDeleted(const QString &item);
|
||||||
|
|
||||||
|
void updateOkButton(const QString &text);
|
||||||
|
|
||||||
void on_newProfileAction_triggered();
|
void on_newProfileAction_triggered();
|
||||||
void on_deleteProfileAction_triggered();
|
void on_deleteProfileAction_triggered();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
QMenu *mContextMenu;
|
TextInputDialog *mProfileDialog;
|
||||||
|
|
||||||
Files::ConfigurationManager &mCfgMgr;
|
Files::ConfigurationManager &mCfgMgr;
|
||||||
|
|
||||||
GameSettings &mGameSettings;
|
Config::GameSettings &mGameSettings;
|
||||||
LauncherSettings &mLauncherSettings;
|
Config::LauncherSettings &mLauncherSettings;
|
||||||
|
|
||||||
|
QString mPreviousProfile;
|
||||||
|
|
||||||
QString mDataLocal;
|
QString mDataLocal;
|
||||||
|
|
||||||
void setPluginsCheckstates(Qt::CheckState state);
|
void setPluginsCheckstates(Qt::CheckState state);
|
||||||
|
|
||||||
void buildView();
|
void buildView();
|
||||||
void setupDataFiles();
|
|
||||||
void setupConfig();
|
void setupConfig();
|
||||||
void readConfig();
|
void readConfig();
|
||||||
void setProfile (int index, bool savePrevious);
|
void setProfile (int index, bool savePrevious);
|
||||||
|
|
|
@ -137,6 +137,7 @@ bool Launcher::GraphicsPage::setupSDL()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
screenComboBox->clear();
|
||||||
for (int i = 0; i < displays; i++)
|
for (int i = 0; i < displays; i++)
|
||||||
{
|
{
|
||||||
screenComboBox->addItem(QString(tr("Screen ")) + QString::number(i + 1));
|
screenComboBox->addItem(QString(tr("Screen ")) + QString::number(i + 1));
|
||||||
|
@ -149,7 +150,7 @@ bool Launcher::GraphicsPage::loadSettings()
|
||||||
{
|
{
|
||||||
if (!setupSDL())
|
if (!setupSDL())
|
||||||
return false;
|
return false;
|
||||||
if (!setupOgre())
|
if (!mOgre && !setupOgre())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (mGraphicsSettings.value(QString("Video/vsync")) == QLatin1String("true"))
|
if (mGraphicsSettings.value(QString("Video/vsync")) == QLatin1String("true"))
|
||||||
|
@ -158,6 +159,9 @@ bool Launcher::GraphicsPage::loadSettings()
|
||||||
if (mGraphicsSettings.value(QString("Video/fullscreen")) == QLatin1String("true"))
|
if (mGraphicsSettings.value(QString("Video/fullscreen")) == QLatin1String("true"))
|
||||||
fullScreenCheckBox->setCheckState(Qt::Checked);
|
fullScreenCheckBox->setCheckState(Qt::Checked);
|
||||||
|
|
||||||
|
if (mGraphicsSettings.value(QString("Video/window border")) == QLatin1String("true"))
|
||||||
|
windowBorderCheckBox->setCheckState(Qt::Checked);
|
||||||
|
|
||||||
int aaIndex = antiAliasingComboBox->findText(mGraphicsSettings.value(QString("Video/antialiasing")));
|
int aaIndex = antiAliasingComboBox->findText(mGraphicsSettings.value(QString("Video/antialiasing")));
|
||||||
if (aaIndex != -1)
|
if (aaIndex != -1)
|
||||||
antiAliasingComboBox->setCurrentIndex(aaIndex);
|
antiAliasingComboBox->setCurrentIndex(aaIndex);
|
||||||
|
@ -192,6 +196,9 @@ void Launcher::GraphicsPage::saveSettings()
|
||||||
fullScreenCheckBox->checkState() ? mGraphicsSettings.setValue(QString("Video/fullscreen"), QString("true"))
|
fullScreenCheckBox->checkState() ? mGraphicsSettings.setValue(QString("Video/fullscreen"), QString("true"))
|
||||||
: mGraphicsSettings.setValue(QString("Video/fullscreen"), QString("false"));
|
: mGraphicsSettings.setValue(QString("Video/fullscreen"), QString("false"));
|
||||||
|
|
||||||
|
windowBorderCheckBox->checkState() ? mGraphicsSettings.setValue(QString("Video/window border"), QString("true"))
|
||||||
|
: mGraphicsSettings.setValue(QString("Video/window border"), QString("false"));
|
||||||
|
|
||||||
mGraphicsSettings.setValue(QString("Video/antialiasing"), antiAliasingComboBox->currentText());
|
mGraphicsSettings.setValue(QString("Video/antialiasing"), antiAliasingComboBox->currentText());
|
||||||
mGraphicsSettings.setValue(QString("Video/render system"), rendererComboBox->currentText());
|
mGraphicsSettings.setValue(QString("Video/render system"), rendererComboBox->currentText());
|
||||||
|
|
||||||
|
@ -330,10 +337,12 @@ void Launcher::GraphicsPage::slotFullScreenChanged(int state)
|
||||||
customRadioButton->setEnabled(false);
|
customRadioButton->setEnabled(false);
|
||||||
customWidthSpinBox->setEnabled(false);
|
customWidthSpinBox->setEnabled(false);
|
||||||
customHeightSpinBox->setEnabled(false);
|
customHeightSpinBox->setEnabled(false);
|
||||||
|
windowBorderCheckBox->setEnabled(false);
|
||||||
} else {
|
} else {
|
||||||
customRadioButton->setEnabled(true);
|
customRadioButton->setEnabled(true);
|
||||||
customWidthSpinBox->setEnabled(true);
|
customWidthSpinBox->setEnabled(true);
|
||||||
customHeightSpinBox->setEnabled(true);
|
customHeightSpinBox->setEnabled(true);
|
||||||
|
windowBorderCheckBox->setEnabled(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,11 +52,14 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
Launcher::MainDialog mainWin;
|
Launcher::MainDialog mainWin;
|
||||||
|
|
||||||
if (mainWin.setup()) {
|
if (!mainWin.showFirstRunDialog())
|
||||||
mainWin.show();
|
|
||||||
} else {
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
|
// if (!mainWin.setup()) {
|
||||||
|
// return 0;
|
||||||
|
// }
|
||||||
|
|
||||||
|
mainWin.show();
|
||||||
|
|
||||||
int returnValue = app.exec();
|
int returnValue = app.exec();
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
|
|
|
@ -5,29 +5,24 @@
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QDate>
|
#include <QDate>
|
||||||
#include <QTime>
|
#include <QTime>
|
||||||
|
#include <QMessageBox>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
#include <QFontDatabase>
|
#include <QFontDatabase>
|
||||||
#include <QInputDialog>
|
#include <QInputDialog>
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QCloseEvent>
|
#include <QCloseEvent>
|
||||||
#include <QTextCodec>
|
#include <QTextCodec>
|
||||||
#include <QProcess>
|
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
#ifndef WIN32
|
|
||||||
#include "unshieldthread.hpp"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "textslotmsgbox.hpp"
|
|
||||||
|
|
||||||
#include "utils/checkablemessagebox.hpp"
|
|
||||||
|
|
||||||
#include "playpage.hpp"
|
#include "playpage.hpp"
|
||||||
#include "graphicspage.hpp"
|
#include "graphicspage.hpp"
|
||||||
#include "datafilespage.hpp"
|
#include "datafilespage.hpp"
|
||||||
|
#include "settingspage.hpp"
|
||||||
|
|
||||||
|
using namespace Process;
|
||||||
|
|
||||||
Launcher::MainDialog::MainDialog(QWidget *parent)
|
Launcher::MainDialog::MainDialog(QWidget *parent)
|
||||||
: mGameSettings(mCfgMgr), QMainWindow (parent)
|
: mGameSettings(mCfgMgr), QMainWindow (parent)
|
||||||
|
@ -53,6 +48,15 @@ Launcher::MainDialog::MainDialog(QWidget *parent)
|
||||||
|
|
||||||
setupUi(this);
|
setupUi(this);
|
||||||
|
|
||||||
|
mGameInvoker = new ProcessInvoker();
|
||||||
|
mWizardInvoker = new ProcessInvoker();
|
||||||
|
|
||||||
|
connect(mWizardInvoker->getProcess(), SIGNAL(started()),
|
||||||
|
this, SLOT(wizardStarted()));
|
||||||
|
|
||||||
|
connect(mWizardInvoker->getProcess(), SIGNAL(finished(int,QProcess::ExitStatus)),
|
||||||
|
this, SLOT(wizardFinished(int,QProcess::ExitStatus)));
|
||||||
|
|
||||||
iconWidget->setViewMode(QListView::IconMode);
|
iconWidget->setViewMode(QListView::IconMode);
|
||||||
iconWidget->setWrapping(false);
|
iconWidget->setWrapping(false);
|
||||||
iconWidget->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); // Just to be sure
|
iconWidget->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); // Just to be sure
|
||||||
|
@ -79,13 +83,13 @@ Launcher::MainDialog::MainDialog(QWidget *parent)
|
||||||
if (!revision.isEmpty() && !tag.isEmpty())
|
if (!revision.isEmpty() && !tag.isEmpty())
|
||||||
{
|
{
|
||||||
if (revision == tag) {
|
if (revision == tag) {
|
||||||
versionLabel->setText(tr("OpenMW %0 release").arg(OPENMW_VERSION));
|
versionLabel->setText(tr("OpenMW %1 release").arg(OPENMW_VERSION));
|
||||||
} else {
|
} else {
|
||||||
versionLabel->setText(tr("OpenMW development (%0)").arg(revision.left(10)));
|
versionLabel->setText(tr("OpenMW development (%1)").arg(revision.left(10)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the compile date and time
|
// Add the compile date and time
|
||||||
versionLabel->setToolTip(tr("Compiled on %0 %1").arg(QLocale(QLocale::C).toDate(QString(__DATE__).simplified(),
|
versionLabel->setToolTip(tr("Compiled on %1 %2").arg(QLocale(QLocale::C).toDate(QString(__DATE__).simplified(),
|
||||||
QLatin1String("MMM d yyyy")).toString(Qt::SystemLocaleLongDate),
|
QLatin1String("MMM d yyyy")).toString(Qt::SystemLocaleLongDate),
|
||||||
QLocale(QLocale::C).toTime(QString(__TIME__).simplified(),
|
QLocale(QLocale::C).toTime(QString(__TIME__).simplified(),
|
||||||
QLatin1String("hh:mm:ss")).toString(Qt::SystemLocaleShortDate)));
|
QLatin1String("hh:mm:ss")).toString(Qt::SystemLocaleShortDate)));
|
||||||
|
@ -94,32 +98,41 @@ Launcher::MainDialog::MainDialog(QWidget *parent)
|
||||||
createIcons();
|
createIcons();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Launcher::MainDialog::~MainDialog()
|
||||||
|
{
|
||||||
|
delete mGameInvoker;
|
||||||
|
delete mWizardInvoker;
|
||||||
|
}
|
||||||
|
|
||||||
void Launcher::MainDialog::createIcons()
|
void Launcher::MainDialog::createIcons()
|
||||||
{
|
{
|
||||||
if (!QIcon::hasThemeIcon("document-new"))
|
if (!QIcon::hasThemeIcon("document-new"))
|
||||||
QIcon::setThemeName("tango");
|
QIcon::setThemeName("tango");
|
||||||
|
|
||||||
// We create a fallback icon because the default fallback doesn't work
|
|
||||||
QIcon graphicsIcon = QIcon(":/icons/tango/video-display.png");
|
|
||||||
|
|
||||||
QListWidgetItem *playButton = new QListWidgetItem(iconWidget);
|
QListWidgetItem *playButton = new QListWidgetItem(iconWidget);
|
||||||
playButton->setIcon(QIcon(":/images/openmw.png"));
|
playButton->setIcon(QIcon(":/images/openmw.png"));
|
||||||
playButton->setText(tr("Play"));
|
playButton->setText(tr("Play"));
|
||||||
playButton->setTextAlignment(Qt::AlignCenter);
|
playButton->setTextAlignment(Qt::AlignCenter);
|
||||||
playButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
|
playButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
|
||||||
|
|
||||||
QListWidgetItem *graphicsButton = new QListWidgetItem(iconWidget);
|
|
||||||
graphicsButton->setIcon(QIcon::fromTheme("video-display", graphicsIcon));
|
|
||||||
graphicsButton->setText(tr("Graphics"));
|
|
||||||
graphicsButton->setTextAlignment(Qt::AlignHCenter | Qt::AlignBottom | Qt::AlignAbsolute);
|
|
||||||
graphicsButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
|
|
||||||
|
|
||||||
QListWidgetItem *dataFilesButton = new QListWidgetItem(iconWidget);
|
QListWidgetItem *dataFilesButton = new QListWidgetItem(iconWidget);
|
||||||
dataFilesButton->setIcon(QIcon(":/images/openmw-plugin.png"));
|
dataFilesButton->setIcon(QIcon(":/images/openmw-plugin.png"));
|
||||||
dataFilesButton->setText(tr("Data Files"));
|
dataFilesButton->setText(tr("Data Files"));
|
||||||
dataFilesButton->setTextAlignment(Qt::AlignHCenter | Qt::AlignBottom);
|
dataFilesButton->setTextAlignment(Qt::AlignHCenter | Qt::AlignBottom);
|
||||||
dataFilesButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
|
dataFilesButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
|
||||||
|
|
||||||
|
QListWidgetItem *graphicsButton = new QListWidgetItem(iconWidget);
|
||||||
|
graphicsButton->setIcon(QIcon::fromTheme("video-display"));
|
||||||
|
graphicsButton->setText(tr("Graphics"));
|
||||||
|
graphicsButton->setTextAlignment(Qt::AlignHCenter | Qt::AlignBottom | Qt::AlignAbsolute);
|
||||||
|
graphicsButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
|
||||||
|
|
||||||
|
QListWidgetItem *settingsButton = new QListWidgetItem(iconWidget);
|
||||||
|
settingsButton->setIcon(QIcon::fromTheme("preferences-system"));
|
||||||
|
settingsButton->setText(tr("Settings"));
|
||||||
|
settingsButton->setTextAlignment(Qt::AlignHCenter | Qt::AlignBottom);
|
||||||
|
settingsButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
|
||||||
|
|
||||||
connect(iconWidget,
|
connect(iconWidget,
|
||||||
SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)),
|
SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)),
|
||||||
this, SLOT(changePage(QListWidgetItem*,QListWidgetItem*)));
|
this, SLOT(changePage(QListWidgetItem*,QListWidgetItem*)));
|
||||||
|
@ -129,8 +142,9 @@ void Launcher::MainDialog::createIcons()
|
||||||
void Launcher::MainDialog::createPages()
|
void Launcher::MainDialog::createPages()
|
||||||
{
|
{
|
||||||
mPlayPage = new PlayPage(this);
|
mPlayPage = new PlayPage(this);
|
||||||
mGraphicsPage = new GraphicsPage(mCfgMgr, mGraphicsSettings, this);
|
|
||||||
mDataFilesPage = new DataFilesPage(mCfgMgr, mGameSettings, mLauncherSettings, this);
|
mDataFilesPage = new DataFilesPage(mCfgMgr, mGameSettings, mLauncherSettings, this);
|
||||||
|
mGraphicsPage = new GraphicsPage(mCfgMgr, mGraphicsSettings, this);
|
||||||
|
mSettingsPage = new SettingsPage(mCfgMgr, mGameSettings, mLauncherSettings, this);
|
||||||
|
|
||||||
// Set the combobox of the play page to imitate the combobox on the datafilespage
|
// Set the combobox of the play page to imitate the combobox on the datafilespage
|
||||||
mPlayPage->setProfilesModel(mDataFilesPage->profilesModel());
|
mPlayPage->setProfilesModel(mDataFilesPage->profilesModel());
|
||||||
|
@ -138,8 +152,9 @@ void Launcher::MainDialog::createPages()
|
||||||
|
|
||||||
// Add the pages to the stacked widget
|
// Add the pages to the stacked widget
|
||||||
pagesWidget->addWidget(mPlayPage);
|
pagesWidget->addWidget(mPlayPage);
|
||||||
pagesWidget->addWidget(mGraphicsPage);
|
|
||||||
pagesWidget->addWidget(mDataFilesPage);
|
pagesWidget->addWidget(mDataFilesPage);
|
||||||
|
pagesWidget->addWidget(mGraphicsPage);
|
||||||
|
pagesWidget->addWidget(mSettingsPage);
|
||||||
|
|
||||||
// Select the first page
|
// Select the first page
|
||||||
iconWidget->setCurrentItem(iconWidget->item(0), QItemSelectionModel::Select);
|
iconWidget->setCurrentItem(iconWidget->item(0), QItemSelectionModel::Select);
|
||||||
|
@ -153,153 +168,63 @@ void Launcher::MainDialog::createPages()
|
||||||
|
|
||||||
bool Launcher::MainDialog::showFirstRunDialog()
|
bool Launcher::MainDialog::showFirstRunDialog()
|
||||||
{
|
{
|
||||||
QStringList iniPaths;
|
if (!setupLauncherSettings())
|
||||||
|
return false;
|
||||||
|
|
||||||
foreach (const QString &path, mGameSettings.getDataDirs()) {
|
if (mLauncherSettings.value(QString("General/firstrun"), QString("true")) == QLatin1String("true"))
|
||||||
QDir dir(path);
|
|
||||||
dir.setPath(dir.canonicalPath()); // Resolve symlinks
|
|
||||||
|
|
||||||
if (dir.exists(QString("Morrowind.ini")))
|
|
||||||
iniPaths.append(dir.absoluteFilePath(QString("Morrowind.ini")));
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
if (!dir.cdUp())
|
|
||||||
continue; // Cannot move from Data Files
|
|
||||||
|
|
||||||
if (dir.exists(QString("Morrowind.ini")))
|
|
||||||
iniPaths.append(dir.absoluteFilePath(QString("Morrowind.ini")));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ask the user where the Morrowind.ini is
|
|
||||||
if (iniPaths.empty()) {
|
|
||||||
QMessageBox msgBox;
|
QMessageBox msgBox;
|
||||||
msgBox.setWindowTitle(tr("Error detecting Morrowind configuration"));
|
msgBox.setWindowTitle(tr("First run"));
|
||||||
msgBox.setIcon(QMessageBox::Warning);
|
msgBox.setIcon(QMessageBox::Question);
|
||||||
msgBox.setStandardButtons(QMessageBox::Cancel);
|
msgBox.setStandardButtons(QMessageBox::NoButton);
|
||||||
msgBox.setText(QObject::tr("<br><b>Could not find Morrowind.ini</b><br><br> \
|
msgBox.setText(tr("<html><head/><body><p><b>Welcome to OpenMW!</b></p> \
|
||||||
OpenMW needs to import settings from this file.<br><br> \
|
<p>It is recommended to run the Installation Wizard.</p> \
|
||||||
Press \"Browse...\" to specify the location manually.<br>"));
|
<p>The Wizard will let you select an existing Morrowind installation, \
|
||||||
|
or install Morrowind for OpenMW to use.</p></body></html>"));
|
||||||
|
|
||||||
QAbstractButton *dirSelectButton =
|
QAbstractButton *wizardButton =
|
||||||
msgBox.addButton(QObject::tr("B&rowse..."), QMessageBox::ActionRole);
|
msgBox.addButton(tr("Run &Installation Wizard"), QMessageBox::AcceptRole); // ActionRole doesn't work?!
|
||||||
|
|
||||||
msgBox.exec();
|
|
||||||
|
|
||||||
QString iniFile;
|
|
||||||
if (msgBox.clickedButton() == dirSelectButton) {
|
|
||||||
iniFile = QFileDialog::getOpenFileName(
|
|
||||||
NULL,
|
|
||||||
QObject::tr("Select configuration file"),
|
|
||||||
QDir::currentPath(),
|
|
||||||
QString(tr("Morrowind configuration file (*.ini)")));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (iniFile.isEmpty())
|
|
||||||
return false; // Cancel was clicked;
|
|
||||||
|
|
||||||
QFileInfo info(iniFile);
|
|
||||||
iniPaths.clear();
|
|
||||||
iniPaths.append(info.absoluteFilePath());
|
|
||||||
}
|
|
||||||
|
|
||||||
CheckableMessageBox msgBox(this);
|
|
||||||
msgBox.setWindowTitle(tr("Morrowind installation detected"));
|
|
||||||
|
|
||||||
QIcon icon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxQuestion);
|
|
||||||
int size = QApplication::style()->pixelMetric(QStyle::PM_MessageBoxIconSize);
|
|
||||||
msgBox.setIconPixmap(icon.pixmap(size, size));
|
|
||||||
|
|
||||||
QAbstractButton *importerButton =
|
|
||||||
msgBox.addButton(tr("Import"), QDialogButtonBox::AcceptRole); // ActionRole doesn't work?!
|
|
||||||
QAbstractButton *skipButton =
|
QAbstractButton *skipButton =
|
||||||
msgBox.addButton(tr("Skip"), QDialogButtonBox::RejectRole);
|
msgBox.addButton(tr("Skip"), QMessageBox::RejectRole);
|
||||||
|
|
||||||
Q_UNUSED(skipButton); // Surpress compiler unused warning
|
Q_UNUSED(skipButton); // Surpress compiler unused warning
|
||||||
|
|
||||||
msgBox.setStandardButtons(QDialogButtonBox::NoButton);
|
|
||||||
msgBox.setText(tr("<br><b>An existing Morrowind configuration was detected</b><br> \
|
|
||||||
<br>Would you like to import settings from Morrowind.ini?<br> \
|
|
||||||
<br><b>Warning: In most cases OpenMW needs these settings to run properly</b><br>"));
|
|
||||||
msgBox.setCheckBoxText(tr("Include selected masters and plugins (creates a new profile)"));
|
|
||||||
msgBox.exec();
|
msgBox.exec();
|
||||||
|
|
||||||
|
if (msgBox.clickedButton() == wizardButton)
|
||||||
if (msgBox.clickedButton() == importerButton) {
|
{
|
||||||
|
if (!mWizardInvoker->startProcess(QLatin1String("openmw-wizard"), false)) {
|
||||||
if (iniPaths.count() > 1) {
|
return false;
|
||||||
// Multiple Morrowind.ini files found
|
|
||||||
bool ok;
|
|
||||||
QString path = QInputDialog::getItem(this, tr("Multiple configurations found"),
|
|
||||||
tr("<br><b>There are multiple Morrowind.ini files found.</b><br><br> \
|
|
||||||
Please select the one you wish to import from:"), iniPaths, 0, false, &ok);
|
|
||||||
if (ok && !path.isEmpty()) {
|
|
||||||
iniPaths.clear();
|
|
||||||
iniPaths.append(path);
|
|
||||||
} else {
|
} else {
|
||||||
// Cancel was clicked
|
return true;
|
||||||
return false;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the file if it doesn't already exist, else the importer will fail
|
return setup();
|
||||||
QString path = QString::fromUtf8(mCfgMgr.getUserConfigPath().string().c_str()) + QString("openmw.cfg");
|
|
||||||
QFile file(path);
|
|
||||||
|
|
||||||
if (!file.exists()) {
|
|
||||||
if (!file.open(QIODevice::ReadWrite)) {
|
|
||||||
// File cannot be created
|
|
||||||
QMessageBox msgBox;
|
|
||||||
msgBox.setWindowTitle(tr("Error writing OpenMW configuration file"));
|
|
||||||
msgBox.setIcon(QMessageBox::Critical);
|
|
||||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
|
||||||
msgBox.setText(tr("<br><b>Could not open or create %0 for writing</b><br><br> \
|
|
||||||
Please make sure you have the right permissions \
|
|
||||||
and try again.<br>").arg(file.fileName()));
|
|
||||||
msgBox.exec();
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
file.close();
|
bool Launcher::MainDialog::setup()
|
||||||
}
|
{
|
||||||
|
|
||||||
// Construct the arguments to run the importer
|
|
||||||
QStringList arguments;
|
|
||||||
|
|
||||||
if (msgBox.isChecked())
|
|
||||||
arguments.append(QString("--game-files"));
|
|
||||||
|
|
||||||
arguments.append(QString("--encoding"));
|
|
||||||
arguments.append(mGameSettings.value(QString("encoding"), QString("win1252")));
|
|
||||||
arguments.append(QString("--ini"));
|
|
||||||
arguments.append(iniPaths.first());
|
|
||||||
arguments.append(QString("--cfg"));
|
|
||||||
arguments.append(path);
|
|
||||||
|
|
||||||
if (!startProgram(QString("mwiniimport"), arguments, false))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Re-read the game settings
|
|
||||||
if (!setupGameSettings())
|
if (!setupGameSettings())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Add a new profile
|
if (!setupGraphicsSettings())
|
||||||
if (msgBox.isChecked()) {
|
return false;
|
||||||
mLauncherSettings.setValue(QString("Profiles/currentprofile"), QString("Imported"));
|
|
||||||
mLauncherSettings.remove(QString("Profiles/Imported/content"));
|
|
||||||
|
|
||||||
QStringList contents = mGameSettings.values(QString("content"));
|
// Now create the pages as they need the settings
|
||||||
foreach (const QString &content, contents) {
|
createPages();
|
||||||
mLauncherSettings.setMultiValue(QString("Profiles/Imported/content"), content);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
// Call this so we can exit on Ogre/SDL errors before mainwindow is shown
|
||||||
|
if (!mGraphicsPage->loadSettings())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
loadSettings();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Launcher::MainDialog::setup()
|
bool Launcher::MainDialog::reloadSettings()
|
||||||
{
|
{
|
||||||
if (!setupLauncherSettings())
|
if (!setupLauncherSettings())
|
||||||
return false;
|
return false;
|
||||||
|
@ -310,21 +235,15 @@ bool Launcher::MainDialog::setup()
|
||||||
if (!setupGraphicsSettings())
|
if (!setupGraphicsSettings())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Check if we need to show the importer
|
if (!mSettingsPage->loadSettings())
|
||||||
if (mLauncherSettings.value(QString("General/firstrun"), QString("true")) == QLatin1String("true"))
|
|
||||||
{
|
|
||||||
if (!showFirstRunDialog())
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
// Now create the pages as they need the settings
|
if (!mDataFilesPage->loadSettings())
|
||||||
createPages();
|
return false;
|
||||||
|
|
||||||
// Call this so we can exit on Ogre/SDL errors before mainwindow is shown
|
|
||||||
if (!mGraphicsPage->loadSettings())
|
if (!mGraphicsPage->loadSettings())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
loadSettings();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -334,24 +253,24 @@ void Launcher::MainDialog::changePage(QListWidgetItem *current, QListWidgetItem
|
||||||
current = previous;
|
current = previous;
|
||||||
|
|
||||||
int currentIndex = iconWidget->row(current);
|
int currentIndex = iconWidget->row(current);
|
||||||
int previousIndex = iconWidget->row(previous);
|
// int previousIndex = iconWidget->row(previous);
|
||||||
|
|
||||||
pagesWidget->setCurrentIndex(currentIndex);
|
pagesWidget->setCurrentIndex(currentIndex);
|
||||||
|
|
||||||
DataFilesPage *previousPage = dynamic_cast<DataFilesPage *>(pagesWidget->widget(previousIndex));
|
// DataFilesPage *previousPage = dynamic_cast<DataFilesPage *>(pagesWidget->widget(previousIndex));
|
||||||
DataFilesPage *currentPage = dynamic_cast<DataFilesPage *>(pagesWidget->widget(currentIndex));
|
// DataFilesPage *currentPage = dynamic_cast<DataFilesPage *>(pagesWidget->widget(currentIndex));
|
||||||
|
|
||||||
//special call to update/save data files page list view when it's displayed/hidden.
|
// //special call to update/save data files page list view when it's displayed/hidden.
|
||||||
if (previousPage)
|
// if (previousPage)
|
||||||
{
|
// {
|
||||||
if (previousPage->objectName() == "DataFilesPage")
|
// if (previousPage->objectName() == "DataFilesPage")
|
||||||
previousPage->saveSettings();
|
// previousPage->saveSettings();
|
||||||
}
|
// }
|
||||||
else if (currentPage)
|
// else if (currentPage)
|
||||||
{
|
// {
|
||||||
if (currentPage->objectName() == "DataFilesPage")
|
// if (currentPage->objectName() == "DataFilesPage")
|
||||||
currentPage->loadSettings();
|
// currentPage->loadSettings();
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Launcher::MainDialog::setupLauncherSettings()
|
bool Launcher::MainDialog::setupLauncherSettings()
|
||||||
|
@ -373,7 +292,7 @@ bool Launcher::MainDialog::setupLauncherSettings()
|
||||||
msgBox.setWindowTitle(tr("Error opening OpenMW configuration file"));
|
msgBox.setWindowTitle(tr("Error opening OpenMW configuration file"));
|
||||||
msgBox.setIcon(QMessageBox::Critical);
|
msgBox.setIcon(QMessageBox::Critical);
|
||||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
msgBox.setStandardButtons(QMessageBox::Ok);
|
||||||
msgBox.setText(QObject::tr("<br><b>Could not open %0 for reading</b><br><br> \
|
msgBox.setText(tr("<br><b>Could not open %0 for reading</b><br><br> \
|
||||||
Please make sure you have the right permissions \
|
Please make sure you have the right permissions \
|
||||||
and try again.<br>").arg(file.fileName()));
|
and try again.<br>").arg(file.fileName()));
|
||||||
msgBox.exec();
|
msgBox.exec();
|
||||||
|
@ -390,78 +309,6 @@ bool Launcher::MainDialog::setupLauncherSettings()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef WIN32
|
|
||||||
bool Launcher::expansions(Launcher::UnshieldThread& cd)
|
|
||||||
{
|
|
||||||
if(cd.BloodmoonDone())
|
|
||||||
{
|
|
||||||
cd.Done();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
QMessageBox expansionsBox;
|
|
||||||
expansionsBox.setText(QObject::tr("<br>Would you like to install expansions now ? (make sure you have the disc)<br> \
|
|
||||||
If you want to install both Bloodmoon and Tribunal, you have to install Tribunal first.<br>"));
|
|
||||||
|
|
||||||
QAbstractButton* tribunalButton = NULL;
|
|
||||||
if(!cd.TribunalDone())
|
|
||||||
tribunalButton = expansionsBox.addButton(QObject::tr("&Tribunal"), QMessageBox::ActionRole);
|
|
||||||
|
|
||||||
QAbstractButton* bloodmoonButton = expansionsBox.addButton(QObject::tr("&Bloodmoon"), QMessageBox::ActionRole);
|
|
||||||
QAbstractButton* noneButton = expansionsBox.addButton(QObject::tr("&None"), QMessageBox::ActionRole);
|
|
||||||
|
|
||||||
expansionsBox.exec();
|
|
||||||
|
|
||||||
if(expansionsBox.clickedButton() == noneButton)
|
|
||||||
{
|
|
||||||
cd.Done();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else if(expansionsBox.clickedButton() == tribunalButton)
|
|
||||||
{
|
|
||||||
|
|
||||||
TextSlotMsgBox cdbox;
|
|
||||||
cdbox.setStandardButtons(QMessageBox::Cancel);
|
|
||||||
|
|
||||||
QObject::connect(&cd,SIGNAL(signalGUI(const QString&)), &cdbox, SLOT(setTextSlot(const QString&)));
|
|
||||||
QObject::connect(&cd,SIGNAL(close()), &cdbox, SLOT(reject()));
|
|
||||||
|
|
||||||
cd.SetTribunalPath(
|
|
||||||
QFileDialog::getOpenFileName(
|
|
||||||
NULL,
|
|
||||||
QObject::tr("Select data1.hdr from Tribunal Installation CD (Tribunal/data1.hdr on GOTY CDs)"),
|
|
||||||
QDir::currentPath(),
|
|
||||||
QString(QObject::tr("Installshield hdr file (*.hdr)"))).toUtf8().constData());
|
|
||||||
|
|
||||||
cd.start();
|
|
||||||
cdbox.exec();
|
|
||||||
}
|
|
||||||
else if(expansionsBox.clickedButton() == bloodmoonButton)
|
|
||||||
{
|
|
||||||
|
|
||||||
TextSlotMsgBox cdbox;
|
|
||||||
cdbox.setStandardButtons(QMessageBox::Cancel);
|
|
||||||
|
|
||||||
QObject::connect(&cd,SIGNAL(signalGUI(const QString&)), &cdbox, SLOT(setTextSlot(const QString&)));
|
|
||||||
QObject::connect(&cd,SIGNAL(close()), &cdbox, SLOT(reject()));
|
|
||||||
|
|
||||||
cd.SetBloodmoonPath(
|
|
||||||
QFileDialog::getOpenFileName(
|
|
||||||
NULL,
|
|
||||||
QObject::tr("Select data1.hdr from Bloodmoon Installation CD (Bloodmoon/data1.hdr on GOTY CDs)"),
|
|
||||||
QDir::currentPath(),
|
|
||||||
QString(QObject::tr("Installshield hdr file (*.hdr)"))).toUtf8().constData());
|
|
||||||
|
|
||||||
cd.start();
|
|
||||||
cdbox.exec();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
#endif // WIN32
|
|
||||||
|
|
||||||
bool Launcher::MainDialog::setupGameSettings()
|
bool Launcher::MainDialog::setupGameSettings()
|
||||||
{
|
{
|
||||||
QString userPath = QString::fromUtf8(mCfgMgr.getUserConfigPath().string().c_str());
|
QString userPath = QString::fromUtf8(mCfgMgr.getUserConfigPath().string().c_str());
|
||||||
|
@ -480,7 +327,7 @@ bool Launcher::MainDialog::setupGameSettings()
|
||||||
msgBox.setWindowTitle(tr("Error opening OpenMW configuration file"));
|
msgBox.setWindowTitle(tr("Error opening OpenMW configuration file"));
|
||||||
msgBox.setIcon(QMessageBox::Critical);
|
msgBox.setIcon(QMessageBox::Critical);
|
||||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
msgBox.setStandardButtons(QMessageBox::Ok);
|
||||||
msgBox.setText(QObject::tr("<br><b>Could not open %0 for reading</b><br><br> \
|
msgBox.setText(tr("<br><b>Could not open %0 for reading</b><br><br> \
|
||||||
Please make sure you have the right permissions \
|
Please make sure you have the right permissions \
|
||||||
and try again.<br>").arg(file.fileName()));
|
and try again.<br>").arg(file.fileName()));
|
||||||
msgBox.exec();
|
msgBox.exec();
|
||||||
|
@ -508,7 +355,7 @@ bool Launcher::MainDialog::setupGameSettings()
|
||||||
msgBox.setWindowTitle(tr("Error opening OpenMW configuration file"));
|
msgBox.setWindowTitle(tr("Error opening OpenMW configuration file"));
|
||||||
msgBox.setIcon(QMessageBox::Critical);
|
msgBox.setIcon(QMessageBox::Critical);
|
||||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
msgBox.setStandardButtons(QMessageBox::Ok);
|
||||||
msgBox.setText(QObject::tr("<br><b>Could not open %0 for reading</b><br><br> \
|
msgBox.setText(tr("<br><b>Could not open %0 for reading</b><br><br> \
|
||||||
Please make sure you have the right permissions \
|
Please make sure you have the right permissions \
|
||||||
and try again.<br>").arg(file.fileName()));
|
and try again.<br>").arg(file.fileName()));
|
||||||
msgBox.exec();
|
msgBox.exec();
|
||||||
|
@ -540,72 +387,22 @@ bool Launcher::MainDialog::setupGameSettings()
|
||||||
msgBox.setWindowTitle(tr("Error detecting Morrowind installation"));
|
msgBox.setWindowTitle(tr("Error detecting Morrowind installation"));
|
||||||
msgBox.setIcon(QMessageBox::Warning);
|
msgBox.setIcon(QMessageBox::Warning);
|
||||||
msgBox.setStandardButtons(QMessageBox::Cancel);
|
msgBox.setStandardButtons(QMessageBox::Cancel);
|
||||||
msgBox.setText(QObject::tr("<br><b>Could not find the Data Files location</b><br><br> \
|
msgBox.setText(tr("<br><b>Could not find the Data Files location</b><br><br> \
|
||||||
The directory containing the data files was not found.<br><br> \
|
The directory containing the data files was not found."));
|
||||||
Press \"Browse...\" to specify the location manually.<br>"));
|
|
||||||
|
|
||||||
QAbstractButton *dirSelectButton =
|
|
||||||
msgBox.addButton(QObject::tr("Browse to &Install..."), QMessageBox::ActionRole);
|
|
||||||
|
|
||||||
#ifndef WIN32
|
|
||||||
QAbstractButton *cdSelectButton =
|
|
||||||
msgBox.addButton(QObject::tr("Browse to &CD..."), QMessageBox::ActionRole);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
QAbstractButton *wizardButton =
|
||||||
|
msgBox.addButton(tr("Run &Installation Wizard..."), QMessageBox::ActionRole);
|
||||||
|
|
||||||
msgBox.exec();
|
msgBox.exec();
|
||||||
|
|
||||||
QString selectedFile;
|
if (msgBox.clickedButton() == wizardButton)
|
||||||
if (msgBox.clickedButton() == dirSelectButton) {
|
|
||||||
selectedFile = QFileDialog::getOpenFileName(
|
|
||||||
NULL,
|
|
||||||
QObject::tr("Select master file"),
|
|
||||||
QDir::currentPath(),
|
|
||||||
QString(tr("Morrowind master file (*.esm)")));
|
|
||||||
}
|
|
||||||
#ifndef WIN32
|
|
||||||
else if(msgBox.clickedButton() == cdSelectButton) {
|
|
||||||
UnshieldThread cd;
|
|
||||||
|
|
||||||
{
|
{
|
||||||
TextSlotMsgBox cdbox;
|
if (!mWizardInvoker->startProcess(QLatin1String("openmw-wizard"), false)) {
|
||||||
cdbox.setStandardButtons(QMessageBox::Cancel);
|
return false;
|
||||||
|
} else {
|
||||||
QObject::connect(&cd,SIGNAL(signalGUI(const QString&)), &cdbox, SLOT(setTextSlot(const QString&)));
|
return true;
|
||||||
QObject::connect(&cd,SIGNAL(close()), &cdbox, SLOT(reject()));
|
|
||||||
|
|
||||||
cd.SetMorrowindPath(
|
|
||||||
QFileDialog::getOpenFileName(
|
|
||||||
NULL,
|
|
||||||
QObject::tr("Select data1.hdr from Morrowind Installation CD"),
|
|
||||||
QDir::currentPath(),
|
|
||||||
QString(tr("Installshield hdr file (*.hdr)"))).toUtf8().constData());
|
|
||||||
|
|
||||||
cd.SetOutputPath(
|
|
||||||
QFileDialog::getExistingDirectory(
|
|
||||||
NULL,
|
|
||||||
QObject::tr("Select where to extract files to"),
|
|
||||||
QDir::currentPath(),
|
|
||||||
QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks).toUtf8().constData());
|
|
||||||
|
|
||||||
cd.start();
|
|
||||||
cdbox.exec();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while(expansions(cd));
|
|
||||||
|
|
||||||
selectedFile = QString::fromUtf8(cd.GetMWEsmPath().c_str());
|
|
||||||
}
|
}
|
||||||
#endif // WIN32
|
|
||||||
|
|
||||||
if (selectedFile.isEmpty())
|
|
||||||
return false; // Cancel was clicked;
|
|
||||||
|
|
||||||
QFileInfo info(selectedFile);
|
|
||||||
|
|
||||||
// Add the new dir to the settings file and to the data dir container
|
|
||||||
mGameSettings.setMultiValue(QString("data"), info.absolutePath());
|
|
||||||
mGameSettings.addDataDir(info.absolutePath());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -626,7 +423,7 @@ bool Launcher::MainDialog::setupGraphicsSettings()
|
||||||
msgBox.setWindowTitle(tr("Error reading OpenMW configuration file"));
|
msgBox.setWindowTitle(tr("Error reading OpenMW configuration file"));
|
||||||
msgBox.setIcon(QMessageBox::Critical);
|
msgBox.setIcon(QMessageBox::Critical);
|
||||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
msgBox.setStandardButtons(QMessageBox::Ok);
|
||||||
msgBox.setText(QObject::tr("<br><b>Could not find settings-default.cfg</b><br><br> \
|
msgBox.setText(tr("<br><b>Could not find settings-default.cfg</b><br><br> \
|
||||||
The problem may be due to an incomplete installation of OpenMW.<br> \
|
The problem may be due to an incomplete installation of OpenMW.<br> \
|
||||||
Reinstalling OpenMW may resolve the problem."));
|
Reinstalling OpenMW may resolve the problem."));
|
||||||
msgBox.exec();
|
msgBox.exec();
|
||||||
|
@ -648,7 +445,7 @@ bool Launcher::MainDialog::setupGraphicsSettings()
|
||||||
msgBox.setWindowTitle(tr("Error opening OpenMW configuration file"));
|
msgBox.setWindowTitle(tr("Error opening OpenMW configuration file"));
|
||||||
msgBox.setIcon(QMessageBox::Critical);
|
msgBox.setIcon(QMessageBox::Critical);
|
||||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
msgBox.setStandardButtons(QMessageBox::Ok);
|
||||||
msgBox.setText(QObject::tr("<br><b>Could not open %0 for reading</b><br><br> \
|
msgBox.setText(tr("<br><b>Could not open %0 for reading</b><br><br> \
|
||||||
Please make sure you have the right permissions \
|
Please make sure you have the right permissions \
|
||||||
and try again.<br>").arg(file.fileName()));
|
and try again.<br>").arg(file.fileName()));
|
||||||
msgBox.exec();
|
msgBox.exec();
|
||||||
|
@ -699,8 +496,9 @@ bool Launcher::MainDialog::writeSettings()
|
||||||
{
|
{
|
||||||
// Now write all config files
|
// Now write all config files
|
||||||
saveSettings();
|
saveSettings();
|
||||||
mGraphicsPage->saveSettings();
|
|
||||||
mDataFilesPage->saveSettings();
|
mDataFilesPage->saveSettings();
|
||||||
|
mGraphicsPage->saveSettings();
|
||||||
|
mSettingsPage->saveSettings();
|
||||||
|
|
||||||
QString userPath = QString::fromUtf8(mCfgMgr.getUserConfigPath().string().c_str());
|
QString userPath = QString::fromUtf8(mCfgMgr.getUserConfigPath().string().c_str());
|
||||||
QDir dir(userPath);
|
QDir dir(userPath);
|
||||||
|
@ -794,12 +592,27 @@ void Launcher::MainDialog::closeEvent(QCloseEvent *event)
|
||||||
event->accept();
|
event->accept();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Launcher::MainDialog::wizardStarted()
|
||||||
|
{
|
||||||
|
hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Launcher::MainDialog::wizardFinished(int exitCode, QProcess::ExitStatus exitStatus)
|
||||||
|
{
|
||||||
|
if (exitCode != 0 || exitStatus == QProcess::CrashExit)
|
||||||
|
return qApp->quit();
|
||||||
|
|
||||||
|
// HACK: Ensure the pages are created, else segfault
|
||||||
|
setup();
|
||||||
|
|
||||||
|
if (reloadSettings())
|
||||||
|
show();
|
||||||
|
}
|
||||||
|
|
||||||
void Launcher::MainDialog::play()
|
void Launcher::MainDialog::play()
|
||||||
{
|
{
|
||||||
if (!writeSettings()) {
|
if (!writeSettings())
|
||||||
qApp->quit();
|
return qApp->quit();
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!mGameSettings.hasMaster()) {
|
if (!mGameSettings.hasMaster()) {
|
||||||
QMessageBox msgBox;
|
QMessageBox msgBox;
|
||||||
|
@ -813,103 +626,7 @@ void Launcher::MainDialog::play()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Launch the game detached
|
// Launch the game detached
|
||||||
startProgram(QString("openmw"), true);
|
|
||||||
qApp->quit();
|
if (mGameInvoker->startProcess(QLatin1String("openmw"), true))
|
||||||
}
|
return qApp->quit();
|
||||||
|
|
||||||
bool Launcher::MainDialog::startProgram(const QString &name, const QStringList &arguments, bool detached)
|
|
||||||
{
|
|
||||||
QString path = name;
|
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
path.append(QString(".exe"));
|
|
||||||
#elif defined(Q_OS_MAC)
|
|
||||||
QDir dir(QCoreApplication::applicationDirPath());
|
|
||||||
path = dir.absoluteFilePath(name);
|
|
||||||
#else
|
|
||||||
path.prepend(QString("./"));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
QFile file(path);
|
|
||||||
|
|
||||||
QProcess process;
|
|
||||||
QFileInfo info(file);
|
|
||||||
|
|
||||||
if (!file.exists()) {
|
|
||||||
QMessageBox msgBox;
|
|
||||||
msgBox.setWindowTitle(tr("Error starting executable"));
|
|
||||||
msgBox.setIcon(QMessageBox::Warning);
|
|
||||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
|
||||||
msgBox.setText(tr("<br><b>Could not find %1</b><br><br> \
|
|
||||||
The application is not found.<br> \
|
|
||||||
Please make sure OpenMW is installed correctly and try again.<br>").arg(info.fileName()));
|
|
||||||
msgBox.exec();
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!info.isExecutable()) {
|
|
||||||
QMessageBox msgBox;
|
|
||||||
msgBox.setWindowTitle(tr("Error starting executable"));
|
|
||||||
msgBox.setIcon(QMessageBox::Warning);
|
|
||||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
|
||||||
msgBox.setText(tr("<br><b>Could not start %1</b><br><br> \
|
|
||||||
The application is not executable.<br> \
|
|
||||||
Please make sure you have the right permissions and try again.<br>").arg(info.fileName()));
|
|
||||||
msgBox.exec();
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start the executable
|
|
||||||
if (detached) {
|
|
||||||
if (!process.startDetached(path, arguments)) {
|
|
||||||
QMessageBox msgBox;
|
|
||||||
msgBox.setWindowTitle(tr("Error starting executable"));
|
|
||||||
msgBox.setIcon(QMessageBox::Critical);
|
|
||||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
|
||||||
msgBox.setText(tr("<br><b>Could not start %1</b><br><br> \
|
|
||||||
An error occurred while starting %1.<br><br> \
|
|
||||||
Press \"Show Details...\" for more information.<br>").arg(info.fileName()));
|
|
||||||
msgBox.setDetailedText(process.errorString());
|
|
||||||
msgBox.exec();
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
process.start(path, arguments);
|
|
||||||
if (!process.waitForFinished()) {
|
|
||||||
QMessageBox msgBox;
|
|
||||||
msgBox.setWindowTitle(tr("Error starting executable"));
|
|
||||||
msgBox.setIcon(QMessageBox::Critical);
|
|
||||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
|
||||||
msgBox.setText(tr("<br><b>Could not start %1</b><br><br> \
|
|
||||||
An error occurred while starting %1.<br><br> \
|
|
||||||
Press \"Show Details...\" for more information.<br>").arg(info.fileName()));
|
|
||||||
msgBox.setDetailedText(process.errorString());
|
|
||||||
msgBox.exec();
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (process.exitCode() != 0 || process.exitStatus() == QProcess::CrashExit) {
|
|
||||||
QString error(process.readAllStandardError());
|
|
||||||
error.append(tr("\nArguments:\n"));
|
|
||||||
error.append(arguments.join(" "));
|
|
||||||
|
|
||||||
QMessageBox msgBox;
|
|
||||||
msgBox.setWindowTitle(tr("Error running executable"));
|
|
||||||
msgBox.setIcon(QMessageBox::Critical);
|
|
||||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
|
||||||
msgBox.setText(tr("<br><b>Executable %1 returned an error</b><br><br> \
|
|
||||||
An error occurred while running %1.<br><br> \
|
|
||||||
Press \"Show Details...\" for more information.<br>").arg(info.fileName()));
|
|
||||||
msgBox.setDetailedText(error);
|
|
||||||
msgBox.exec();
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,16 +2,26 @@
|
||||||
#define MAINDIALOG_H
|
#define MAINDIALOG_H
|
||||||
|
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
|
#include <QProcess>
|
||||||
|
|
||||||
#ifndef Q_MOC_RUN
|
#ifndef Q_MOC_RUN
|
||||||
#include <components/files/configurationmanager.hpp>
|
#include <components/files/configurationmanager.hpp>
|
||||||
#endif
|
#endif
|
||||||
#include "settings/gamesettings.hpp"
|
|
||||||
|
#include <components/process/processinvoker.hpp>
|
||||||
|
|
||||||
|
#include <components/config/gamesettings.hpp>
|
||||||
|
#include <components/config/launchersettings.hpp>
|
||||||
|
|
||||||
#include "settings/graphicssettings.hpp"
|
#include "settings/graphicssettings.hpp"
|
||||||
#include "settings/launchersettings.hpp"
|
|
||||||
|
|
||||||
#include "ui_mainwindow.h"
|
#include "ui_mainwindow.h"
|
||||||
|
|
||||||
class QListWidgetItem;
|
class QListWidgetItem;
|
||||||
|
class QStackedWidget;
|
||||||
|
class QStringList;
|
||||||
|
class QStringListModel;
|
||||||
|
class QString;
|
||||||
|
|
||||||
namespace Launcher
|
namespace Launcher
|
||||||
{
|
{
|
||||||
|
@ -19,6 +29,7 @@ namespace Launcher
|
||||||
class GraphicsPage;
|
class GraphicsPage;
|
||||||
class DataFilesPage;
|
class DataFilesPage;
|
||||||
class UnshieldThread;
|
class UnshieldThread;
|
||||||
|
class SettingsPage;
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
bool expansions(Launcher::UnshieldThread& cd);
|
bool expansions(Launcher::UnshieldThread& cd);
|
||||||
|
@ -30,13 +41,22 @@ namespace Launcher
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit MainDialog(QWidget *parent = 0);
|
explicit MainDialog(QWidget *parent = 0);
|
||||||
|
~MainDialog();
|
||||||
|
|
||||||
bool setup();
|
bool setup();
|
||||||
bool showFirstRunDialog();
|
bool showFirstRunDialog();
|
||||||
|
|
||||||
|
bool reloadSettings();
|
||||||
|
bool writeSettings();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void changePage(QListWidgetItem *current, QListWidgetItem *previous);
|
void changePage(QListWidgetItem *current, QListWidgetItem *previous);
|
||||||
void play();
|
void play();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void wizardStarted();
|
||||||
|
void wizardFinished(int exitCode, QProcess::ExitStatus exitStatus);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void createIcons();
|
void createIcons();
|
||||||
void createPages();
|
void createPages();
|
||||||
|
@ -47,7 +67,6 @@ namespace Launcher
|
||||||
|
|
||||||
void loadSettings();
|
void loadSettings();
|
||||||
void saveSettings();
|
void saveSettings();
|
||||||
bool writeSettings();
|
|
||||||
|
|
||||||
inline bool startProgram(const QString &name, bool detached = false) { return startProgram(name, QStringList(), detached); }
|
inline bool startProgram(const QString &name, bool detached = false) { return startProgram(name, QStringList(), detached); }
|
||||||
bool startProgram(const QString &name, const QStringList &arguments, bool detached = false);
|
bool startProgram(const QString &name, const QStringList &arguments, bool detached = false);
|
||||||
|
@ -57,12 +76,16 @@ namespace Launcher
|
||||||
PlayPage *mPlayPage;
|
PlayPage *mPlayPage;
|
||||||
GraphicsPage *mGraphicsPage;
|
GraphicsPage *mGraphicsPage;
|
||||||
DataFilesPage *mDataFilesPage;
|
DataFilesPage *mDataFilesPage;
|
||||||
|
SettingsPage *mSettingsPage;
|
||||||
|
|
||||||
|
Process::ProcessInvoker *mGameInvoker;
|
||||||
|
Process::ProcessInvoker *mWizardInvoker;
|
||||||
|
|
||||||
Files::ConfigurationManager mCfgMgr;
|
Files::ConfigurationManager mCfgMgr;
|
||||||
|
|
||||||
GameSettings mGameSettings;
|
Config::GameSettings mGameSettings;
|
||||||
GraphicsSettings mGraphicsSettings;
|
GraphicsSettings mGraphicsSettings;
|
||||||
LauncherSettings mLauncherSettings;
|
Config::LauncherSettings mLauncherSettings;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
#ifndef GRAPHICSSETTINGS_HPP
|
#ifndef GRAPHICSSETTINGS_HPP
|
||||||
#define GRAPHICSSETTINGS_HPP
|
#define GRAPHICSSETTINGS_HPP
|
||||||
|
|
||||||
#include "settingsbase.hpp"
|
#include <components/config/settingsbase.hpp>
|
||||||
|
|
||||||
namespace Launcher
|
namespace Launcher
|
||||||
{
|
{
|
||||||
class GraphicsSettings : public SettingsBase<QMap<QString, QString> >
|
class GraphicsSettings : public Config::SettingsBase<QMap<QString, QString> >
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GraphicsSettings();
|
GraphicsSettings();
|
||||||
|
|
269
apps/launcher/settingspage.cpp
Normal file
269
apps/launcher/settingspage.cpp
Normal file
|
@ -0,0 +1,269 @@
|
||||||
|
#include "settingspage.hpp"
|
||||||
|
|
||||||
|
#include <QFileDialog>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QDir>
|
||||||
|
|
||||||
|
#include <components/files/configurationmanager.hpp>
|
||||||
|
|
||||||
|
#include <components/config/gamesettings.hpp>
|
||||||
|
#include <components/config/launchersettings.hpp>
|
||||||
|
|
||||||
|
#include "utils/textinputdialog.hpp"
|
||||||
|
|
||||||
|
using namespace Process;
|
||||||
|
|
||||||
|
Launcher::SettingsPage::SettingsPage(Files::ConfigurationManager &cfg,
|
||||||
|
Config::GameSettings &gameSettings,
|
||||||
|
Config::LauncherSettings &launcherSettings, MainDialog *parent)
|
||||||
|
: mCfgMgr(cfg)
|
||||||
|
, mGameSettings(gameSettings)
|
||||||
|
, mLauncherSettings(launcherSettings)
|
||||||
|
, QWidget(parent)
|
||||||
|
, mMain(parent)
|
||||||
|
{
|
||||||
|
setupUi(this);
|
||||||
|
|
||||||
|
QStringList languages;
|
||||||
|
languages << QLatin1String("English")
|
||||||
|
<< QLatin1String("French")
|
||||||
|
<< QLatin1String("German")
|
||||||
|
<< QLatin1String("Italian")
|
||||||
|
<< QLatin1String("Polish")
|
||||||
|
<< QLatin1String("Russian")
|
||||||
|
<< QLatin1String("Spanish");
|
||||||
|
|
||||||
|
languageComboBox->addItems(languages);
|
||||||
|
|
||||||
|
mWizardInvoker = new ProcessInvoker();
|
||||||
|
mImporterInvoker = new ProcessInvoker();
|
||||||
|
|
||||||
|
connect(mWizardInvoker->getProcess(), SIGNAL(started()),
|
||||||
|
this, SLOT(wizardStarted()));
|
||||||
|
|
||||||
|
connect(mWizardInvoker->getProcess(), SIGNAL(finished(int,QProcess::ExitStatus)),
|
||||||
|
this, SLOT(wizardFinished(int,QProcess::ExitStatus)));
|
||||||
|
|
||||||
|
connect(mImporterInvoker->getProcess(), SIGNAL(started()),
|
||||||
|
this, SLOT(importerStarted()));
|
||||||
|
|
||||||
|
connect(mImporterInvoker->getProcess(), SIGNAL(finished(int,QProcess::ExitStatus)),
|
||||||
|
this, SLOT(importerFinished(int,QProcess::ExitStatus)));
|
||||||
|
|
||||||
|
mProfileDialog = new TextInputDialog(tr("New Profile"), tr("Profile name:"), this);
|
||||||
|
|
||||||
|
connect(mProfileDialog->lineEdit(), SIGNAL(textChanged(QString)),
|
||||||
|
this, SLOT(updateOkButton(QString)));
|
||||||
|
|
||||||
|
// Detect Morrowind configuration files
|
||||||
|
QStringList iniPaths;
|
||||||
|
|
||||||
|
foreach (const QString &path, mGameSettings.getDataDirs()) {
|
||||||
|
QDir dir(path);
|
||||||
|
dir.setPath(dir.canonicalPath()); // Resolve symlinks
|
||||||
|
|
||||||
|
if (dir.exists(QString("Morrowind.ini")))
|
||||||
|
iniPaths.append(dir.absoluteFilePath(QString("Morrowind.ini")));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!dir.cdUp())
|
||||||
|
continue; // Cannot move from Data Files
|
||||||
|
|
||||||
|
if (dir.exists(QString("Morrowind.ini")))
|
||||||
|
iniPaths.append(dir.absoluteFilePath(QString("Morrowind.ini")));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!iniPaths.isEmpty()) {
|
||||||
|
settingsComboBox->addItems(iniPaths);
|
||||||
|
importerButton->setEnabled(true);
|
||||||
|
} else {
|
||||||
|
importerButton->setEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
loadSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
Launcher::SettingsPage::~SettingsPage()
|
||||||
|
{
|
||||||
|
delete mWizardInvoker;
|
||||||
|
delete mImporterInvoker;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Launcher::SettingsPage::on_wizardButton_clicked()
|
||||||
|
{
|
||||||
|
saveSettings();
|
||||||
|
|
||||||
|
if (!mWizardInvoker->startProcess(QLatin1String("openmw-wizard"), false))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Launcher::SettingsPage::on_importerButton_clicked()
|
||||||
|
{
|
||||||
|
saveSettings();
|
||||||
|
|
||||||
|
// Create the file if it doesn't already exist, else the importer will fail
|
||||||
|
QString path(QString::fromUtf8(mCfgMgr.getUserConfigPath().string().c_str()));
|
||||||
|
path.append(QLatin1String("openmw.cfg"));
|
||||||
|
QFile file(path);
|
||||||
|
|
||||||
|
if (!file.exists()) {
|
||||||
|
if (!file.open(QIODevice::ReadWrite)) {
|
||||||
|
// File cannot be created
|
||||||
|
QMessageBox msgBox;
|
||||||
|
msgBox.setWindowTitle(tr("Error writing OpenMW configuration file"));
|
||||||
|
msgBox.setIcon(QMessageBox::Critical);
|
||||||
|
msgBox.setStandardButtons(QMessageBox::Ok);
|
||||||
|
msgBox.setText(tr("<html><head/><body><p><b>Could not open or create %1 for writing </b></p> \
|
||||||
|
<p>Please make sure you have the right permissions \
|
||||||
|
and try again.</p></body></html>").arg(file.fileName()));
|
||||||
|
msgBox.exec();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
file.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Construct the arguments to run the importer
|
||||||
|
QStringList arguments;
|
||||||
|
|
||||||
|
if (addonsCheckBox->isChecked())
|
||||||
|
arguments.append(QString("--game-files"));
|
||||||
|
|
||||||
|
arguments.append(QString("--encoding"));
|
||||||
|
arguments.append(mGameSettings.value(QString("encoding"), QString("win1252")));
|
||||||
|
arguments.append(QString("--ini"));
|
||||||
|
arguments.append(settingsComboBox->currentText());
|
||||||
|
arguments.append(QString("--cfg"));
|
||||||
|
arguments.append(path);
|
||||||
|
|
||||||
|
qDebug() << "arguments " << arguments;
|
||||||
|
|
||||||
|
if (!mImporterInvoker->startProcess(QLatin1String("mwiniimport"), arguments, false))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Launcher::SettingsPage::on_browseButton_clicked()
|
||||||
|
{
|
||||||
|
QString iniFile = QFileDialog::getOpenFileName(
|
||||||
|
this,
|
||||||
|
QObject::tr("Select configuration file"),
|
||||||
|
QDir::currentPath(),
|
||||||
|
QString(tr("Morrowind configuration file (*.ini)")));
|
||||||
|
|
||||||
|
|
||||||
|
if (iniFile.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
QFileInfo info(iniFile);
|
||||||
|
|
||||||
|
if (!info.exists() || !info.isReadable())
|
||||||
|
return;
|
||||||
|
|
||||||
|
const QString path(QDir::toNativeSeparators(info.absoluteFilePath()));
|
||||||
|
|
||||||
|
if (settingsComboBox->findText(path) == -1) {
|
||||||
|
settingsComboBox->addItem(path);
|
||||||
|
settingsComboBox->setCurrentIndex(settingsComboBox->findText(path));
|
||||||
|
importerButton->setEnabled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Launcher::SettingsPage::wizardStarted()
|
||||||
|
{
|
||||||
|
mMain->hide(); // Hide the launcher
|
||||||
|
|
||||||
|
wizardButton->setEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Launcher::SettingsPage::wizardFinished(int exitCode, QProcess::ExitStatus exitStatus)
|
||||||
|
{
|
||||||
|
if (exitCode != 0 || exitStatus == QProcess::CrashExit)
|
||||||
|
return qApp->quit();
|
||||||
|
|
||||||
|
mMain->reloadSettings();
|
||||||
|
wizardButton->setEnabled(true);
|
||||||
|
|
||||||
|
mMain->show(); // Show the launcher again
|
||||||
|
}
|
||||||
|
|
||||||
|
void Launcher::SettingsPage::importerStarted()
|
||||||
|
{
|
||||||
|
importerButton->setEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Launcher::SettingsPage::importerFinished(int exitCode, QProcess::ExitStatus exitStatus)
|
||||||
|
{
|
||||||
|
if (exitCode != 0 || exitStatus == QProcess::CrashExit)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Re-read the settings in their current state
|
||||||
|
mMain->reloadSettings();
|
||||||
|
|
||||||
|
// Import selected data files from openmw.cfg
|
||||||
|
if (addonsCheckBox->isChecked())
|
||||||
|
{
|
||||||
|
if (mProfileDialog->exec() == QDialog::Accepted)
|
||||||
|
{
|
||||||
|
const QString profile(mProfileDialog->lineEdit()->text());
|
||||||
|
const QStringList files(mGameSettings.values(QLatin1String("content")));
|
||||||
|
|
||||||
|
qDebug() << "Profile " << profile << files;
|
||||||
|
|
||||||
|
// Doesn't quite work right now
|
||||||
|
mLauncherSettings.setValue(QLatin1String("Profiles/currentprofile"), profile);
|
||||||
|
|
||||||
|
foreach (const QString &file, files) {
|
||||||
|
mLauncherSettings.setMultiValue(QLatin1String("Profiles/") + profile + QLatin1String("/content"), file);
|
||||||
|
}
|
||||||
|
|
||||||
|
mGameSettings.remove(QLatin1String("content"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mMain->reloadSettings();
|
||||||
|
importerButton->setEnabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Launcher::SettingsPage::updateOkButton(const QString &text)
|
||||||
|
{
|
||||||
|
// We do this here because we need to access the profiles
|
||||||
|
if (text.isEmpty()) {
|
||||||
|
mProfileDialog->setOkButtonEnabled(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QStringList profiles(mLauncherSettings.subKeys(QString("Profiles/")));
|
||||||
|
|
||||||
|
(profiles.contains(text))
|
||||||
|
? mProfileDialog->setOkButtonEnabled(false)
|
||||||
|
: mProfileDialog->setOkButtonEnabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Launcher::SettingsPage::saveSettings()
|
||||||
|
{
|
||||||
|
QString language(languageComboBox->currentText());
|
||||||
|
|
||||||
|
mLauncherSettings.setValue(QLatin1String("Settings/language"), language);
|
||||||
|
|
||||||
|
if (language == QLatin1String("Polish")) {
|
||||||
|
mGameSettings.setValue(QLatin1String("encoding"), QLatin1String("win1250"));
|
||||||
|
} else if (language == QLatin1String("Russian")) {
|
||||||
|
mGameSettings.setValue(QLatin1String("encoding"), QLatin1String("win1251"));
|
||||||
|
} else {
|
||||||
|
mGameSettings.setValue(QLatin1String("encoding"), QLatin1String("win1252"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Launcher::SettingsPage::loadSettings()
|
||||||
|
{
|
||||||
|
QString language(mLauncherSettings.value(QLatin1String("Settings/language")));
|
||||||
|
|
||||||
|
int index = languageComboBox->findText(language);
|
||||||
|
|
||||||
|
if (index != -1)
|
||||||
|
languageComboBox->setCurrentIndex(index);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
64
apps/launcher/settingspage.hpp
Normal file
64
apps/launcher/settingspage.hpp
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
#ifndef SETTINGSPAGE_HPP
|
||||||
|
#define SETTINGSPAGE_HPP
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QProcess>
|
||||||
|
|
||||||
|
#include <components/process/processinvoker.hpp>
|
||||||
|
|
||||||
|
#include "ui_settingspage.h"
|
||||||
|
|
||||||
|
#include "maindialog.hpp"
|
||||||
|
|
||||||
|
namespace Files { struct ConfigurationManager; }
|
||||||
|
namespace Config { class GameSettings;
|
||||||
|
class LauncherSettings; }
|
||||||
|
|
||||||
|
namespace Launcher
|
||||||
|
{
|
||||||
|
class TextInputDialog;
|
||||||
|
|
||||||
|
class SettingsPage : public QWidget, private Ui::SettingsPage
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
SettingsPage(Files::ConfigurationManager &cfg, Config::GameSettings &gameSettings,
|
||||||
|
Config::LauncherSettings &launcherSettings, MainDialog *parent = 0);
|
||||||
|
~SettingsPage();
|
||||||
|
|
||||||
|
void saveSettings();
|
||||||
|
bool loadSettings();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
|
||||||
|
void on_wizardButton_clicked();
|
||||||
|
void on_importerButton_clicked();
|
||||||
|
void on_browseButton_clicked();
|
||||||
|
|
||||||
|
void wizardStarted();
|
||||||
|
void wizardFinished(int exitCode, QProcess::ExitStatus exitStatus);
|
||||||
|
|
||||||
|
void importerStarted();
|
||||||
|
void importerFinished(int exitCode, QProcess::ExitStatus exitStatus);
|
||||||
|
|
||||||
|
void updateOkButton(const QString &text);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
Process::ProcessInvoker *mWizardInvoker;
|
||||||
|
Process::ProcessInvoker *mImporterInvoker;
|
||||||
|
|
||||||
|
Files::ConfigurationManager &mCfgMgr;
|
||||||
|
|
||||||
|
Config::GameSettings &mGameSettings;
|
||||||
|
Config::LauncherSettings &mLauncherSettings;
|
||||||
|
|
||||||
|
MainDialog *mMain;
|
||||||
|
TextInputDialog *mProfileDialog;
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // SETTINGSPAGE_HPP
|
|
@ -1,521 +0,0 @@
|
||||||
#include "unshieldthread.hpp"
|
|
||||||
|
|
||||||
#include <boost/filesystem/fstream.hpp>
|
|
||||||
#include <components/misc/stringops.hpp>
|
|
||||||
|
|
||||||
namespace bfs = boost::filesystem;
|
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
static bool make_sure_directory_exists(bfs::path directory)
|
|
||||||
{
|
|
||||||
|
|
||||||
if(!bfs::exists(directory))
|
|
||||||
{
|
|
||||||
bfs::create_directories(directory);
|
|
||||||
}
|
|
||||||
|
|
||||||
return bfs::exists(directory);
|
|
||||||
}
|
|
||||||
|
|
||||||
void fill_path(bfs::path& path, const std::string& name)
|
|
||||||
{
|
|
||||||
size_t start = 0;
|
|
||||||
|
|
||||||
size_t i;
|
|
||||||
for(i = 0; i < name.length(); i++)
|
|
||||||
{
|
|
||||||
switch(name[i])
|
|
||||||
{
|
|
||||||
case '\\':
|
|
||||||
path /= name.substr(start, i-start);
|
|
||||||
start = i+1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
path /= name.substr(start, i-start);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string get_setting(const std::string& category, const std::string& setting, const std::string& inx)
|
|
||||||
{
|
|
||||||
size_t start = inx.find(category);
|
|
||||||
start = inx.find(setting, start) + setting.length() + 3;
|
|
||||||
|
|
||||||
size_t end = inx.find("!", start);
|
|
||||||
|
|
||||||
return inx.substr(start, end-start);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string read_to_string(const bfs::path& path)
|
|
||||||
{
|
|
||||||
bfs::ifstream strstream(path, std::ios::in | std::ios::binary);
|
|
||||||
std::string str;
|
|
||||||
|
|
||||||
strstream.seekg(0, std::ios::end);
|
|
||||||
str.resize(strstream.tellg());
|
|
||||||
strstream.seekg(0, std::ios::beg);
|
|
||||||
strstream.read(&str[0], str.size());
|
|
||||||
strstream.close();
|
|
||||||
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
void add_setting(const std::string& category, const std::string& setting, const std::string& val, std::string& ini)
|
|
||||||
{
|
|
||||||
size_t loc;
|
|
||||||
loc = ini.find("[" + category + "]");
|
|
||||||
|
|
||||||
// If category is not found, create it
|
|
||||||
if(loc == std::string::npos)
|
|
||||||
{
|
|
||||||
loc = ini.size() + 2;
|
|
||||||
ini += ("\r\n[" + category + "]\r\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
loc += category.length() +2 +2;
|
|
||||||
ini.insert(loc, setting + "=" + val + "\r\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
#define FIX(setting) add_setting(category, setting, get_setting(category, setting, inx), ini)
|
|
||||||
|
|
||||||
void bloodmoon_fix_ini(std::string& ini, const bfs::path inxPath)
|
|
||||||
{
|
|
||||||
std::string inx = read_to_string(inxPath);
|
|
||||||
|
|
||||||
// Remove this one setting (the only one actually changed by bloodmoon, as opposed to just adding new ones)
|
|
||||||
size_t start = ini.find("[Weather Blight]");
|
|
||||||
start = ini.find("Ambient Loop Sound ID", start);
|
|
||||||
size_t end = ini.find("\r\n", start) +2;
|
|
||||||
ini.erase(start, end-start);
|
|
||||||
|
|
||||||
std::string category;
|
|
||||||
|
|
||||||
category = "General";
|
|
||||||
{
|
|
||||||
FIX("Werewolf FOV");
|
|
||||||
}
|
|
||||||
category = "Moons";
|
|
||||||
{
|
|
||||||
FIX("Script Color");
|
|
||||||
}
|
|
||||||
category = "Weather";
|
|
||||||
{
|
|
||||||
FIX("Snow Ripples");
|
|
||||||
FIX("Snow Ripple Radius");
|
|
||||||
FIX("Snow Ripples Per Flake");
|
|
||||||
FIX("Snow Ripple Scale");
|
|
||||||
FIX("Snow Ripple Speed");
|
|
||||||
FIX("Snow Gravity Scale");
|
|
||||||
FIX("Snow High Kill");
|
|
||||||
FIX("Snow Low Kill");
|
|
||||||
}
|
|
||||||
category = "Weather Blight";
|
|
||||||
{
|
|
||||||
FIX("Ambient Loop Sound ID");
|
|
||||||
}
|
|
||||||
category = "Weather Snow";
|
|
||||||
{
|
|
||||||
FIX("Sky Sunrise Color");
|
|
||||||
FIX("Sky Day Color");
|
|
||||||
FIX("Sky Sunset Color");
|
|
||||||
FIX("Sky Night Color");
|
|
||||||
FIX("Fog Sunrise Color");
|
|
||||||
FIX("Fog Day Color");
|
|
||||||
FIX("Fog Sunset Color");
|
|
||||||
FIX("Fog Night Color");
|
|
||||||
FIX("Ambient Sunrise Color");
|
|
||||||
FIX("Ambient Day Color");
|
|
||||||
FIX("Ambient Sunset Color");
|
|
||||||
FIX("Ambient Night Color");
|
|
||||||
FIX("Sun Sunrise Color");
|
|
||||||
FIX("Sun Day Color");
|
|
||||||
FIX("Sun Sunset Color");
|
|
||||||
FIX("Sun Night Color");
|
|
||||||
FIX("Sun Disc Sunset Color");
|
|
||||||
FIX("Transition Delta");
|
|
||||||
FIX("Land Fog Day Depth");
|
|
||||||
FIX("Land Fog Night Depth");
|
|
||||||
FIX("Clouds Maximum Percent");
|
|
||||||
FIX("Wind Speed");
|
|
||||||
FIX("Cloud Speed");
|
|
||||||
FIX("Glare View");
|
|
||||||
FIX("Cloud Texture");
|
|
||||||
FIX("Ambient Loop Sound ID");
|
|
||||||
FIX("Snow Threshold");
|
|
||||||
FIX("Snow Diameter");
|
|
||||||
FIX("Snow Height Min");
|
|
||||||
FIX("Snow Height Max");
|
|
||||||
FIX("Snow Entrance Speed");
|
|
||||||
FIX("Max Snowflakes");
|
|
||||||
}
|
|
||||||
category = "Weather Blizzard";
|
|
||||||
{
|
|
||||||
FIX("Sky Sunrise Color");
|
|
||||||
FIX("Sky Day Color");
|
|
||||||
FIX("Sky Sunset Color");
|
|
||||||
FIX("Sky Night Color");
|
|
||||||
FIX("Fog Sunrise Color");
|
|
||||||
FIX("Fog Day Color");
|
|
||||||
FIX("Fog Sunset Color");
|
|
||||||
FIX("Fog Night Color");
|
|
||||||
FIX("Ambient Sunrise Color");
|
|
||||||
FIX("Ambient Day Color");
|
|
||||||
FIX("Ambient Sunset Color");
|
|
||||||
FIX("Ambient Night Color");
|
|
||||||
FIX("Sun Sunrise Color");
|
|
||||||
FIX("Sun Day Color");
|
|
||||||
FIX("Sun Sunset Color");
|
|
||||||
FIX("Sun Night Color");
|
|
||||||
FIX("Sun Disc Sunset Color");
|
|
||||||
FIX("Transition Delta");
|
|
||||||
FIX("Land Fog Day Depth");
|
|
||||||
FIX("Land Fog Night Depth");
|
|
||||||
FIX("Clouds Maximum Percent");
|
|
||||||
FIX("Wind Speed");
|
|
||||||
FIX("Cloud Speed");
|
|
||||||
FIX("Glare View");
|
|
||||||
FIX("Cloud Texture");
|
|
||||||
FIX("Ambient Loop Sound ID");
|
|
||||||
FIX("Storm Threshold");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void fix_ini(const bfs::path& output_dir, bfs::path cdPath, bool tribunal, bool bloodmoon)
|
|
||||||
{
|
|
||||||
bfs::path ini_path = output_dir;
|
|
||||||
ini_path /= "Morrowind.ini";
|
|
||||||
|
|
||||||
std::string ini = read_to_string(ini_path.string());
|
|
||||||
|
|
||||||
if(tribunal)
|
|
||||||
{
|
|
||||||
add_setting("Game Files", "GameFile1", "Tribunal.esm", ini);
|
|
||||||
add_setting("Archives", "Archive 0", "Tribunal.bsa", ini);
|
|
||||||
}
|
|
||||||
if(bloodmoon)
|
|
||||||
{
|
|
||||||
bloodmoon_fix_ini(ini, cdPath / "setup.inx");
|
|
||||||
add_setting("Game Files", "GameFile2", "Bloodmoon.esm", ini);
|
|
||||||
add_setting("Archives", "Archive 1", "Bloodmoon.bsa", ini);
|
|
||||||
}
|
|
||||||
|
|
||||||
bfs::ofstream inistream((ini_path));
|
|
||||||
inistream << ini;
|
|
||||||
inistream.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
void installToPath(const bfs::path& from, const bfs::path& to, bool copy = false)
|
|
||||||
{
|
|
||||||
make_sure_directory_exists(to);
|
|
||||||
|
|
||||||
for ( bfs::directory_iterator end, dir(from); dir != end; ++dir )
|
|
||||||
{
|
|
||||||
if(bfs::is_directory(dir->path()))
|
|
||||||
installToPath(dir->path(), to / dir->path().filename(), copy);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(copy)
|
|
||||||
{
|
|
||||||
bfs::path dest = to / dir->path().filename();
|
|
||||||
if(bfs::exists(dest))
|
|
||||||
bfs::remove_all(dest);
|
|
||||||
bfs::copy_file(dir->path(), dest);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
bfs::rename(dir->path(), to / dir->path().filename());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bfs::path findFile(const bfs::path& in, std::string filename, bool recursive = true)
|
|
||||||
{
|
|
||||||
if(recursive)
|
|
||||||
{
|
|
||||||
for ( bfs::recursive_directory_iterator end, dir(in); dir != end; ++dir )
|
|
||||||
{
|
|
||||||
if(Misc::StringUtils::ciEqual(dir->path().filename().string(), filename))
|
|
||||||
return dir->path();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for ( bfs::directory_iterator end, dir(in); dir != end; ++dir )
|
|
||||||
{
|
|
||||||
if(Misc::StringUtils::ciEqual(dir->path().filename().string(), filename))
|
|
||||||
return dir->path();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
bool contains(const bfs::path& in, std::string filename)
|
|
||||||
{
|
|
||||||
for(bfs::directory_iterator end, dir(in); dir != end; ++dir)
|
|
||||||
{
|
|
||||||
if(Misc::StringUtils::ciEqual(dir->path().filename().string(), filename))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
time_t getTime(const char* time)
|
|
||||||
{
|
|
||||||
struct tm tms;
|
|
||||||
memset(&tms, 0, sizeof(struct tm));
|
|
||||||
strptime(time, "%d %B %Y", &tms);
|
|
||||||
return mktime(&tms);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Some cds have cab files which have the Data Files subfolders outside the Data Files folder
|
|
||||||
void install_dfiles_outside(const bfs::path& from, const bfs::path& dFiles)
|
|
||||||
{
|
|
||||||
bfs::path fonts = findFile(from, "fonts", false);
|
|
||||||
if(fonts.string() != "")
|
|
||||||
installToPath(fonts, dFiles / "Fonts");
|
|
||||||
|
|
||||||
bfs::path music = findFile(from, "music", false);
|
|
||||||
if(music.string() != "")
|
|
||||||
installToPath(music, dFiles / "Music");
|
|
||||||
|
|
||||||
bfs::path sound = findFile(from, "sound", false);
|
|
||||||
if(sound.string() != "")
|
|
||||||
installToPath(sound, dFiles / "Sound");
|
|
||||||
|
|
||||||
bfs::path splash = findFile(from, "splash", false);
|
|
||||||
if(splash.string() != "")
|
|
||||||
installToPath(splash, dFiles / "Splash");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Launcher::UnshieldThread::SetMorrowindPath(const std::string& path)
|
|
||||||
{
|
|
||||||
mMorrowindPath = path;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Launcher::UnshieldThread::SetTribunalPath(const std::string& path)
|
|
||||||
{
|
|
||||||
mTribunalPath = path;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Launcher::UnshieldThread::SetBloodmoonPath(const std::string& path)
|
|
||||||
{
|
|
||||||
mBloodmoonPath = path;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Launcher::UnshieldThread::SetOutputPath(const std::string& path)
|
|
||||||
{
|
|
||||||
mOutputPath = path;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Launcher::UnshieldThread::extract_file(Unshield* unshield, bfs::path output_dir, const char* prefix, int index)
|
|
||||||
{
|
|
||||||
bool success;
|
|
||||||
bfs::path dirname;
|
|
||||||
bfs::path filename;
|
|
||||||
int directory = unshield_file_directory(unshield, index);
|
|
||||||
|
|
||||||
dirname = output_dir;
|
|
||||||
|
|
||||||
if (prefix && prefix[0])
|
|
||||||
dirname /= prefix;
|
|
||||||
|
|
||||||
if (directory >= 0)
|
|
||||||
{
|
|
||||||
const char* tmp = unshield_directory_name(unshield, directory);
|
|
||||||
if (tmp && tmp[0])
|
|
||||||
fill_path(dirname, tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
make_sure_directory_exists(dirname);
|
|
||||||
|
|
||||||
filename = dirname;
|
|
||||||
filename /= unshield_file_name(unshield, index);
|
|
||||||
|
|
||||||
emit signalGUI(QString("Extracting: ") + QString(filename.c_str()));
|
|
||||||
|
|
||||||
success = unshield_file_save(unshield, index, filename.c_str());
|
|
||||||
|
|
||||||
if (!success)
|
|
||||||
bfs::remove(filename);
|
|
||||||
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Launcher::UnshieldThread::extract_cab(const bfs::path& cab, const bfs::path& output_dir, bool extract_ini)
|
|
||||||
{
|
|
||||||
Unshield * unshield;
|
|
||||||
unshield = unshield_open(cab.c_str());
|
|
||||||
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < unshield_file_group_count(unshield); i++)
|
|
||||||
{
|
|
||||||
UnshieldFileGroup* file_group = unshield_file_group_get(unshield, i);
|
|
||||||
|
|
||||||
for (size_t j = file_group->first_file; j <= file_group->last_file; j++)
|
|
||||||
{
|
|
||||||
if (unshield_file_is_valid(unshield, j))
|
|
||||||
extract_file(unshield, output_dir, file_group->name, j);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
unshield_close(unshield);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Launcher::UnshieldThread::extract()
|
|
||||||
{
|
|
||||||
bfs::path outputDataFilesDir = mOutputPath;
|
|
||||||
outputDataFilesDir /= "Data Files";
|
|
||||||
bfs::path extractPath = mOutputPath;
|
|
||||||
extractPath /= "extract-temp";
|
|
||||||
|
|
||||||
if(!mMorrowindDone && mMorrowindPath.string().length() > 0)
|
|
||||||
{
|
|
||||||
mMorrowindDone = true;
|
|
||||||
|
|
||||||
bfs::path mwExtractPath = extractPath / "morrowind";
|
|
||||||
extract_cab(mMorrowindPath, mwExtractPath, true);
|
|
||||||
|
|
||||||
bfs::path dFilesDir = findFile(mwExtractPath, "morrowind.esm").parent_path();
|
|
||||||
|
|
||||||
installToPath(dFilesDir, outputDataFilesDir);
|
|
||||||
|
|
||||||
install_dfiles_outside(mwExtractPath, outputDataFilesDir);
|
|
||||||
|
|
||||||
// Videos are often kept uncompressed on the cd
|
|
||||||
bfs::path videosPath = findFile(mMorrowindPath.parent_path(), "video", false);
|
|
||||||
if(videosPath.string() != "")
|
|
||||||
{
|
|
||||||
emit signalGUI(QString("Installing Videos..."));
|
|
||||||
installToPath(videosPath, outputDataFilesDir / "Video", true);
|
|
||||||
}
|
|
||||||
|
|
||||||
bfs::path cdDFiles = findFile(mMorrowindPath.parent_path(), "data files", false);
|
|
||||||
if(cdDFiles.string() != "")
|
|
||||||
{
|
|
||||||
emit signalGUI(QString("Installing Uncompressed Data files from CD..."));
|
|
||||||
installToPath(cdDFiles, outputDataFilesDir, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bfs::rename(findFile(mwExtractPath, "morrowind.ini"), outputDataFilesDir / "Morrowind.ini");
|
|
||||||
|
|
||||||
mTribunalDone = contains(outputDataFilesDir, "tribunal.esm");
|
|
||||||
mBloodmoonDone = contains(outputDataFilesDir, "bloodmoon.esm");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
else if(!mTribunalDone && mTribunalPath.string().length() > 0)
|
|
||||||
{
|
|
||||||
mTribunalDone = true;
|
|
||||||
|
|
||||||
bfs::path tbExtractPath = extractPath / "tribunal";
|
|
||||||
extract_cab(mTribunalPath, tbExtractPath, true);
|
|
||||||
|
|
||||||
bfs::path dFilesDir = findFile(tbExtractPath, "tribunal.esm").parent_path();
|
|
||||||
|
|
||||||
installToPath(dFilesDir, outputDataFilesDir);
|
|
||||||
|
|
||||||
install_dfiles_outside(tbExtractPath, outputDataFilesDir);
|
|
||||||
|
|
||||||
// Mt GOTY CD has Sounds in a seperate folder from the rest of the data files
|
|
||||||
bfs::path soundsPath = findFile(tbExtractPath, "sounds", false);
|
|
||||||
if(soundsPath.string() != "")
|
|
||||||
installToPath(soundsPath, outputDataFilesDir / "Sounds");
|
|
||||||
|
|
||||||
bfs::path cdDFiles = findFile(mTribunalPath.parent_path(), "data files", false);
|
|
||||||
if(cdDFiles.string() != "")
|
|
||||||
{
|
|
||||||
emit signalGUI(QString("Installing Uncompressed Data files from CD..."));
|
|
||||||
installToPath(cdDFiles, outputDataFilesDir, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
mBloodmoonDone = contains(outputDataFilesDir, "bloodmoon.esm");
|
|
||||||
|
|
||||||
fix_ini(outputDataFilesDir, bfs::path(mTribunalPath).parent_path(), mTribunalDone, mBloodmoonDone);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if(!mBloodmoonDone && mBloodmoonPath.string().length() > 0)
|
|
||||||
{
|
|
||||||
mBloodmoonDone = true;
|
|
||||||
|
|
||||||
bfs::path bmExtractPath = extractPath / "bloodmoon";
|
|
||||||
extract_cab(mBloodmoonPath, bmExtractPath, true);
|
|
||||||
|
|
||||||
bfs::path dFilesDir = findFile(bmExtractPath, "bloodmoon.esm").parent_path();
|
|
||||||
|
|
||||||
installToPath(dFilesDir, outputDataFilesDir);
|
|
||||||
|
|
||||||
install_dfiles_outside(bmExtractPath, outputDataFilesDir);
|
|
||||||
|
|
||||||
// My GOTY CD contains a folder within cab files called Tribunal patch,
|
|
||||||
// which contains Tribunal.esm
|
|
||||||
bfs::path tbPatchPath = findFile(bmExtractPath, "tribunal.esm");
|
|
||||||
if(tbPatchPath.string() != "")
|
|
||||||
bfs::rename(tbPatchPath, outputDataFilesDir / "Tribunal.esm");
|
|
||||||
|
|
||||||
bfs::path cdDFiles = findFile(mBloodmoonPath.parent_path(), "data files", false);
|
|
||||||
if(cdDFiles.string() != "")
|
|
||||||
{
|
|
||||||
emit signalGUI(QString("Installing Uncompressed Data files from CD..."));
|
|
||||||
installToPath(cdDFiles, outputDataFilesDir, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
fix_ini(outputDataFilesDir, bfs::path(mBloodmoonPath).parent_path(), false, mBloodmoonDone);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Launcher::UnshieldThread::Done()
|
|
||||||
{
|
|
||||||
// Get rid of unnecessary files
|
|
||||||
bfs::remove_all(mOutputPath / "extract-temp");
|
|
||||||
|
|
||||||
// Set modified time to release dates, to preserve load order
|
|
||||||
if(mMorrowindDone)
|
|
||||||
bfs::last_write_time(findFile(mOutputPath, "morrowind.esm"), getTime("1 May 2002"));
|
|
||||||
|
|
||||||
if(mTribunalDone)
|
|
||||||
bfs::last_write_time(findFile(mOutputPath, "tribunal.esm"), getTime("6 November 2002"));
|
|
||||||
|
|
||||||
if(mBloodmoonDone)
|
|
||||||
bfs::last_write_time(findFile(mOutputPath, "bloodmoon.esm"), getTime("3 June 2003"));
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Launcher::UnshieldThread::GetMWEsmPath()
|
|
||||||
{
|
|
||||||
return findFile(mOutputPath / "Data Files", "morrowind.esm").string();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Launcher::UnshieldThread::TribunalDone()
|
|
||||||
{
|
|
||||||
return mTribunalDone;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Launcher::UnshieldThread::BloodmoonDone()
|
|
||||||
{
|
|
||||||
return mBloodmoonDone;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Launcher::UnshieldThread::run()
|
|
||||||
{
|
|
||||||
extract();
|
|
||||||
emit close();
|
|
||||||
}
|
|
||||||
|
|
||||||
Launcher::UnshieldThread::UnshieldThread()
|
|
||||||
{
|
|
||||||
unshield_set_log_level(0);
|
|
||||||
mMorrowindDone = false;
|
|
||||||
mTribunalDone = false;
|
|
||||||
mBloodmoonDone = false;
|
|
||||||
}
|
|
|
@ -1,58 +0,0 @@
|
||||||
#ifndef UNSHIELD_THREAD_H
|
|
||||||
#define UNSHIELD_THREAD_H
|
|
||||||
|
|
||||||
#include <QThread>
|
|
||||||
|
|
||||||
#include <boost/filesystem.hpp>
|
|
||||||
|
|
||||||
#include <libunshield.h>
|
|
||||||
|
|
||||||
namespace Launcher
|
|
||||||
{
|
|
||||||
class UnshieldThread : public QThread
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
bool SetMorrowindPath(const std::string& path);
|
|
||||||
bool SetTribunalPath(const std::string& path);
|
|
||||||
bool SetBloodmoonPath(const std::string& path);
|
|
||||||
|
|
||||||
void SetOutputPath(const std::string& path);
|
|
||||||
|
|
||||||
bool extract();
|
|
||||||
|
|
||||||
bool TribunalDone();
|
|
||||||
bool BloodmoonDone();
|
|
||||||
|
|
||||||
void Done();
|
|
||||||
|
|
||||||
std::string GetMWEsmPath();
|
|
||||||
|
|
||||||
UnshieldThread();
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
void extract_cab(const boost::filesystem::path& cab, const boost::filesystem::path& output_dir, bool extract_ini = false);
|
|
||||||
bool extract_file(Unshield* unshield, boost::filesystem::path output_dir, const char* prefix, int index);
|
|
||||||
|
|
||||||
boost::filesystem::path mMorrowindPath;
|
|
||||||
boost::filesystem::path mTribunalPath;
|
|
||||||
boost::filesystem::path mBloodmoonPath;
|
|
||||||
|
|
||||||
bool mMorrowindDone;
|
|
||||||
bool mTribunalDone;
|
|
||||||
bool mBloodmoonDone;
|
|
||||||
|
|
||||||
boost::filesystem::path mOutputPath;
|
|
||||||
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual void run();
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void signalGUI(QString);
|
|
||||||
void close();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
#endif
|
|
|
@ -1,258 +0,0 @@
|
||||||
/****************************************************************************
|
|
||||||
**
|
|
||||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
|
||||||
** Contact: http://www.qt-project.org/legal
|
|
||||||
**
|
|
||||||
** This file is part of Qt Creator.
|
|
||||||
**
|
|
||||||
** Commercial License Usage
|
|
||||||
** Licensees holding valid commercial Qt licenses may use this file in
|
|
||||||
** accordance with the commercial license agreement provided with the
|
|
||||||
** Software or, alternatively, in accordance with the terms contained in
|
|
||||||
** a written agreement between you and Digia. For licensing terms and
|
|
||||||
** conditions see http://qt.digia.com/licensing. For further information
|
|
||||||
** use the contact form at http://qt.digia.com/contact-us.
|
|
||||||
**
|
|
||||||
** GNU Lesser General Public License Usage
|
|
||||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
|
||||||
** General Public License version 2.1 as published by the Free Software
|
|
||||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
|
||||||
** packaging of this file. Please review the following information to
|
|
||||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
|
||||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
|
||||||
**
|
|
||||||
** In addition, as a special exception, Digia gives you certain additional
|
|
||||||
** rights. These rights are described in the Digia Qt LGPL Exception
|
|
||||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
|
||||||
**
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#include "checkablemessagebox.hpp"
|
|
||||||
|
|
||||||
#include <QVariant>
|
|
||||||
|
|
||||||
#include <QPushButton>
|
|
||||||
#include <QAction>
|
|
||||||
#include <QApplication>
|
|
||||||
#include <QButtonGroup>
|
|
||||||
#include <QCheckBox>
|
|
||||||
#include <QDialog>
|
|
||||||
#include <QDialogButtonBox>
|
|
||||||
#include <QHBoxLayout>
|
|
||||||
#include <QHeaderView>
|
|
||||||
#include <QLabel>
|
|
||||||
#include <QSpacerItem>
|
|
||||||
#include <QVBoxLayout>
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
\class Utils::CheckableMessageBox
|
|
||||||
|
|
||||||
\brief A messagebox suitable for questions with a
|
|
||||||
"Do not ask me again" checkbox.
|
|
||||||
|
|
||||||
Emulates the QMessageBox API with
|
|
||||||
static conveniences. The message label can open external URLs.
|
|
||||||
*/
|
|
||||||
Launcher::CheckableMessageBoxPrivate::CheckableMessageBoxPrivate(QDialog *q)
|
|
||||||
: clickedButton(0)
|
|
||||||
{
|
|
||||||
QSizePolicy sizePolicy(QSizePolicy::Minimum, QSizePolicy::Preferred);
|
|
||||||
|
|
||||||
pixmapLabel = new QLabel(q);
|
|
||||||
sizePolicy.setHorizontalStretch(0);
|
|
||||||
sizePolicy.setVerticalStretch(0);
|
|
||||||
sizePolicy.setHeightForWidth(pixmapLabel->sizePolicy().hasHeightForWidth());
|
|
||||||
pixmapLabel->setSizePolicy(sizePolicy);
|
|
||||||
pixmapLabel->setVisible(false);
|
|
||||||
|
|
||||||
QSpacerItem *pixmapSpacer =
|
|
||||||
new QSpacerItem(0, 5, QSizePolicy::Minimum, QSizePolicy::MinimumExpanding);
|
|
||||||
|
|
||||||
messageLabel = new QLabel(q);
|
|
||||||
messageLabel->setMinimumSize(QSize(300, 0));
|
|
||||||
messageLabel->setWordWrap(true);
|
|
||||||
messageLabel->setOpenExternalLinks(true);
|
|
||||||
messageLabel->setTextInteractionFlags(Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse);
|
|
||||||
|
|
||||||
QSpacerItem *checkBoxRightSpacer =
|
|
||||||
new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Minimum);
|
|
||||||
QSpacerItem *buttonSpacer =
|
|
||||||
new QSpacerItem(0, 1, QSizePolicy::Minimum, QSizePolicy::Minimum);
|
|
||||||
|
|
||||||
checkBox = new QCheckBox(q);
|
|
||||||
checkBox->setText(Launcher::CheckableMessageBox::tr("Do not ask again"));
|
|
||||||
|
|
||||||
buttonBox = new QDialogButtonBox(q);
|
|
||||||
buttonBox->setOrientation(Qt::Horizontal);
|
|
||||||
buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok);
|
|
||||||
|
|
||||||
QVBoxLayout *verticalLayout = new QVBoxLayout();
|
|
||||||
verticalLayout->addWidget(pixmapLabel);
|
|
||||||
verticalLayout->addItem(pixmapSpacer);
|
|
||||||
|
|
||||||
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
|
|
||||||
horizontalLayout_2->addLayout(verticalLayout);
|
|
||||||
horizontalLayout_2->addWidget(messageLabel);
|
|
||||||
|
|
||||||
QHBoxLayout *horizontalLayout = new QHBoxLayout();
|
|
||||||
horizontalLayout->addWidget(checkBox);
|
|
||||||
horizontalLayout->addItem(checkBoxRightSpacer);
|
|
||||||
|
|
||||||
QVBoxLayout *verticalLayout_2 = new QVBoxLayout(q);
|
|
||||||
verticalLayout_2->addLayout(horizontalLayout_2);
|
|
||||||
verticalLayout_2->addLayout(horizontalLayout);
|
|
||||||
verticalLayout_2->addItem(buttonSpacer);
|
|
||||||
verticalLayout_2->addWidget(buttonBox);
|
|
||||||
}
|
|
||||||
|
|
||||||
Launcher::CheckableMessageBox::CheckableMessageBox(QWidget *parent) :
|
|
||||||
QDialog(parent),
|
|
||||||
d(new Launcher::CheckableMessageBoxPrivate(this))
|
|
||||||
{
|
|
||||||
setModal(true);
|
|
||||||
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
|
||||||
connect(d->buttonBox, SIGNAL(accepted()), SLOT(accept()));
|
|
||||||
connect(d->buttonBox, SIGNAL(rejected()), SLOT(reject()));
|
|
||||||
connect(d->buttonBox, SIGNAL(clicked(QAbstractButton*)),
|
|
||||||
SLOT(slotClicked(QAbstractButton*)));
|
|
||||||
}
|
|
||||||
|
|
||||||
Launcher::CheckableMessageBox::~CheckableMessageBox()
|
|
||||||
{
|
|
||||||
delete d;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Launcher::CheckableMessageBox::slotClicked(QAbstractButton *b)
|
|
||||||
{
|
|
||||||
d->clickedButton = b;
|
|
||||||
}
|
|
||||||
|
|
||||||
QAbstractButton *Launcher::CheckableMessageBox::clickedButton() const
|
|
||||||
{
|
|
||||||
return d->clickedButton;
|
|
||||||
}
|
|
||||||
|
|
||||||
QDialogButtonBox::StandardButton Launcher::CheckableMessageBox::clickedStandardButton() const
|
|
||||||
{
|
|
||||||
if (d->clickedButton)
|
|
||||||
return d->buttonBox->standardButton(d->clickedButton);
|
|
||||||
return QDialogButtonBox::NoButton;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString Launcher::CheckableMessageBox::text() const
|
|
||||||
{
|
|
||||||
return d->messageLabel->text();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Launcher::CheckableMessageBox::setText(const QString &t)
|
|
||||||
{
|
|
||||||
d->messageLabel->setText(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
QPixmap Launcher::CheckableMessageBox::iconPixmap() const
|
|
||||||
{
|
|
||||||
if (const QPixmap *p = d->pixmapLabel->pixmap())
|
|
||||||
return QPixmap(*p);
|
|
||||||
return QPixmap();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Launcher::CheckableMessageBox::setIconPixmap(const QPixmap &p)
|
|
||||||
{
|
|
||||||
d->pixmapLabel->setPixmap(p);
|
|
||||||
d->pixmapLabel->setVisible(!p.isNull());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Launcher::CheckableMessageBox::isChecked() const
|
|
||||||
{
|
|
||||||
return d->checkBox->isChecked();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Launcher::CheckableMessageBox::setChecked(bool s)
|
|
||||||
{
|
|
||||||
d->checkBox->setChecked(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString Launcher::CheckableMessageBox::checkBoxText() const
|
|
||||||
{
|
|
||||||
return d->checkBox->text();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Launcher::CheckableMessageBox::setCheckBoxText(const QString &t)
|
|
||||||
{
|
|
||||||
d->checkBox->setText(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Launcher::CheckableMessageBox::isCheckBoxVisible() const
|
|
||||||
{
|
|
||||||
return d->checkBox->isVisible();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Launcher::CheckableMessageBox::setCheckBoxVisible(bool v)
|
|
||||||
{
|
|
||||||
d->checkBox->setVisible(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
QDialogButtonBox::StandardButtons Launcher::CheckableMessageBox::standardButtons() const
|
|
||||||
{
|
|
||||||
return d->buttonBox->standardButtons();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Launcher::CheckableMessageBox::setStandardButtons(QDialogButtonBox::StandardButtons s)
|
|
||||||
{
|
|
||||||
d->buttonBox->setStandardButtons(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
QPushButton *Launcher::CheckableMessageBox::button(QDialogButtonBox::StandardButton b) const
|
|
||||||
{
|
|
||||||
return d->buttonBox->button(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
QPushButton *Launcher::CheckableMessageBox::addButton(const QString &text, QDialogButtonBox::ButtonRole role)
|
|
||||||
{
|
|
||||||
return d->buttonBox->addButton(text, role);
|
|
||||||
}
|
|
||||||
|
|
||||||
QDialogButtonBox::StandardButton Launcher::CheckableMessageBox::defaultButton() const
|
|
||||||
{
|
|
||||||
foreach (QAbstractButton *b, d->buttonBox->buttons())
|
|
||||||
if (QPushButton *pb = qobject_cast<QPushButton *>(b))
|
|
||||||
if (pb->isDefault())
|
|
||||||
return d->buttonBox->standardButton(pb);
|
|
||||||
return QDialogButtonBox::NoButton;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Launcher::CheckableMessageBox::setDefaultButton(QDialogButtonBox::StandardButton s)
|
|
||||||
{
|
|
||||||
if (QPushButton *b = d->buttonBox->button(s)) {
|
|
||||||
b->setDefault(true);
|
|
||||||
b->setFocus();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QDialogButtonBox::StandardButton
|
|
||||||
Launcher::CheckableMessageBox::question(QWidget *parent,
|
|
||||||
const QString &title,
|
|
||||||
const QString &question,
|
|
||||||
const QString &checkBoxText,
|
|
||||||
bool *checkBoxSetting,
|
|
||||||
QDialogButtonBox::StandardButtons buttons,
|
|
||||||
QDialogButtonBox::StandardButton defaultButton)
|
|
||||||
{
|
|
||||||
CheckableMessageBox mb(parent);
|
|
||||||
mb.setWindowTitle(title);
|
|
||||||
mb.setIconPixmap(QMessageBox::standardIcon(QMessageBox::Question));
|
|
||||||
mb.setText(question);
|
|
||||||
mb.setCheckBoxText(checkBoxText);
|
|
||||||
mb.setChecked(*checkBoxSetting);
|
|
||||||
mb.setStandardButtons(buttons);
|
|
||||||
mb.setDefaultButton(defaultButton);
|
|
||||||
mb.exec();
|
|
||||||
*checkBoxSetting = mb.isChecked();
|
|
||||||
return mb.clickedStandardButton();
|
|
||||||
}
|
|
||||||
|
|
||||||
QMessageBox::StandardButton Launcher::CheckableMessageBox::dialogButtonBoxToMessageBoxButton(QDialogButtonBox::StandardButton db)
|
|
||||||
{
|
|
||||||
return static_cast<QMessageBox::StandardButton>(int(db));
|
|
||||||
}
|
|
|
@ -1,116 +0,0 @@
|
||||||
/****************************************************************************
|
|
||||||
**
|
|
||||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
|
||||||
** Contact: http://www.qt-project.org/legal
|
|
||||||
**
|
|
||||||
** This file is part of Qt Creator.
|
|
||||||
**
|
|
||||||
** Commercial License Usage
|
|
||||||
** Licensees holding valid commercial Qt licenses may use this file in
|
|
||||||
** accordance with the commercial license agreement provided with the
|
|
||||||
** Software or, alternatively, in accordance with the terms contained in
|
|
||||||
** a written agreement between you and Digia. For licensing terms and
|
|
||||||
** conditions see http://qt.digia.com/licensing. For further information
|
|
||||||
** use the contact form at http://qt.digia.com/contact-us.
|
|
||||||
**
|
|
||||||
** GNU Lesser General Public License Usage
|
|
||||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
|
||||||
** General Public License version 2.1 as published by the Free Software
|
|
||||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
|
||||||
** packaging of this file. Please review the following information to
|
|
||||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
|
||||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
|
||||||
**
|
|
||||||
** In addition, as a special exception, Digia gives you certain additional
|
|
||||||
** rights. These rights are described in the Digia Qt LGPL Exception
|
|
||||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
|
||||||
**
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#ifndef CHECKABLEMESSAGEBOX_HPP
|
|
||||||
#define CHECKABLEMESSAGEBOX_HPP
|
|
||||||
|
|
||||||
#include <QDialogButtonBox>
|
|
||||||
#include <QMessageBox>
|
|
||||||
#include <QDialog>
|
|
||||||
|
|
||||||
class QCheckBox;
|
|
||||||
|
|
||||||
namespace Launcher
|
|
||||||
{
|
|
||||||
class CheckableMessageBoxPrivate
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
QLabel *pixmapLabel;
|
|
||||||
QLabel *messageLabel;
|
|
||||||
QCheckBox *checkBox;
|
|
||||||
QDialogButtonBox *buttonBox;
|
|
||||||
QAbstractButton *clickedButton;
|
|
||||||
|
|
||||||
public:
|
|
||||||
CheckableMessageBoxPrivate(QDialog *q);
|
|
||||||
};
|
|
||||||
|
|
||||||
class CheckableMessageBox : public QDialog
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
Q_PROPERTY(QString text READ text WRITE setText)
|
|
||||||
Q_PROPERTY(QPixmap iconPixmap READ iconPixmap WRITE setIconPixmap)
|
|
||||||
Q_PROPERTY(bool isChecked READ isChecked WRITE setChecked)
|
|
||||||
Q_PROPERTY(QString checkBoxText READ checkBoxText WRITE setCheckBoxText)
|
|
||||||
Q_PROPERTY(QDialogButtonBox::StandardButtons buttons READ standardButtons WRITE setStandardButtons)
|
|
||||||
Q_PROPERTY(QDialogButtonBox::StandardButton defaultButton READ defaultButton WRITE setDefaultButton)
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit CheckableMessageBox(QWidget *parent);
|
|
||||||
virtual ~CheckableMessageBox();
|
|
||||||
|
|
||||||
static QDialogButtonBox::StandardButton
|
|
||||||
question(QWidget *parent,
|
|
||||||
const QString &title,
|
|
||||||
const QString &question,
|
|
||||||
const QString &checkBoxText,
|
|
||||||
bool *checkBoxSetting,
|
|
||||||
QDialogButtonBox::StandardButtons buttons = QDialogButtonBox::Yes|QDialogButtonBox::No,
|
|
||||||
QDialogButtonBox::StandardButton defaultButton = QDialogButtonBox::No);
|
|
||||||
|
|
||||||
QString text() const;
|
|
||||||
void setText(const QString &);
|
|
||||||
|
|
||||||
bool isChecked() const;
|
|
||||||
void setChecked(bool s);
|
|
||||||
|
|
||||||
QString checkBoxText() const;
|
|
||||||
void setCheckBoxText(const QString &);
|
|
||||||
|
|
||||||
bool isCheckBoxVisible() const;
|
|
||||||
void setCheckBoxVisible(bool);
|
|
||||||
|
|
||||||
QDialogButtonBox::StandardButtons standardButtons() const;
|
|
||||||
void setStandardButtons(QDialogButtonBox::StandardButtons s);
|
|
||||||
QPushButton *button(QDialogButtonBox::StandardButton b) const;
|
|
||||||
QPushButton *addButton(const QString &text, QDialogButtonBox::ButtonRole role);
|
|
||||||
|
|
||||||
QDialogButtonBox::StandardButton defaultButton() const;
|
|
||||||
void setDefaultButton(QDialogButtonBox::StandardButton s);
|
|
||||||
|
|
||||||
// See static QMessageBox::standardPixmap()
|
|
||||||
QPixmap iconPixmap() const;
|
|
||||||
void setIconPixmap (const QPixmap &p);
|
|
||||||
|
|
||||||
// Query the result
|
|
||||||
QAbstractButton *clickedButton() const;
|
|
||||||
QDialogButtonBox::StandardButton clickedStandardButton() const;
|
|
||||||
|
|
||||||
// Conversion convenience
|
|
||||||
static QMessageBox::StandardButton dialogButtonBoxToMessageBoxButton(QDialogButtonBox::StandardButton);
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void slotClicked(QAbstractButton *b);
|
|
||||||
|
|
||||||
private:
|
|
||||||
CheckableMessageBoxPrivate *d;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
#endif // CHECKABLEMESSAGEBOX_HPP
|
|
|
@ -47,13 +47,13 @@ void ProfilesComboBox::setEditEnabled(bool editable)
|
||||||
|
|
||||||
void ProfilesComboBox::slotTextChanged(const QString &text)
|
void ProfilesComboBox::slotTextChanged(const QString &text)
|
||||||
{
|
{
|
||||||
QPalette *palette = new QPalette();
|
QPalette palette;
|
||||||
palette->setColor(QPalette::Text,Qt::red);
|
palette.setColor(QPalette::Text,Qt::red);
|
||||||
|
|
||||||
int index = findText(text);
|
int index = findText(text);
|
||||||
|
|
||||||
if (text.isEmpty() || (index != -1 && index != currentIndex())) {
|
if (text.isEmpty() || (index != -1 && index != currentIndex())) {
|
||||||
lineEdit()->setPalette(*palette);
|
lineEdit()->setPalette(palette);
|
||||||
} else {
|
} else {
|
||||||
lineEdit()->setPalette(QApplication::palette());
|
lineEdit()->setPalette(QApplication::palette());
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,15 +16,15 @@ Launcher::TextInputDialog::TextInputDialog(const QString& title, const QString &
|
||||||
mButtonBox->addButton(QDialogButtonBox::Cancel);
|
mButtonBox->addButton(QDialogButtonBox::Cancel);
|
||||||
mButtonBox->button(QDialogButtonBox::Ok)->setEnabled (false);
|
mButtonBox->button(QDialogButtonBox::Ok)->setEnabled (false);
|
||||||
|
|
||||||
// Line edit
|
|
||||||
QValidator *validator = new QRegExpValidator(QRegExp("^[a-zA-Z0-9_]*$"), this); // Alpha-numeric + underscore
|
|
||||||
mLineEdit = new DialogLineEdit(this);
|
|
||||||
mLineEdit->setValidator(validator);
|
|
||||||
mLineEdit->setCompleter(0);
|
|
||||||
|
|
||||||
QLabel *label = new QLabel(this);
|
QLabel *label = new QLabel(this);
|
||||||
label->setText(text);
|
label->setText(text);
|
||||||
|
|
||||||
|
// Line edit
|
||||||
|
QValidator *validator = new QRegExpValidator(QRegExp("^[a-zA-Z0-9_]*$"), this); // Alpha-numeric + underscore
|
||||||
|
mLineEdit = new LineEdit(this);
|
||||||
|
mLineEdit->setValidator(validator);
|
||||||
|
mLineEdit->setCompleter(0);
|
||||||
|
|
||||||
QVBoxLayout *dialogLayout = new QVBoxLayout(this);
|
QVBoxLayout *dialogLayout = new QVBoxLayout(this);
|
||||||
dialogLayout->addWidget(label);
|
dialogLayout->addWidget(label);
|
||||||
dialogLayout->addWidget(mLineEdit);
|
dialogLayout->addWidget(mLineEdit);
|
||||||
|
@ -41,8 +41,10 @@ Launcher::TextInputDialog::TextInputDialog(const QString& title, const QString &
|
||||||
|
|
||||||
connect(mButtonBox, SIGNAL(accepted()), this, SLOT(accept()));
|
connect(mButtonBox, SIGNAL(accepted()), this, SLOT(accept()));
|
||||||
connect(mButtonBox, SIGNAL(rejected()), this, SLOT(reject()));
|
connect(mButtonBox, SIGNAL(rejected()), this, SLOT(reject()));
|
||||||
connect(mLineEdit, SIGNAL(textChanged(QString)), this, SLOT(slotUpdateOkButton(QString)));
|
}
|
||||||
|
|
||||||
|
Launcher::TextInputDialog::~TextInputDialog()
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
int Launcher::TextInputDialog::exec()
|
int Launcher::TextInputDialog::exec()
|
||||||
|
@ -52,36 +54,18 @@ int Launcher::TextInputDialog::exec()
|
||||||
return QDialog::exec();
|
return QDialog::exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Launcher::TextInputDialog::getText() const
|
void Launcher::TextInputDialog::setOkButtonEnabled(bool enabled)
|
||||||
{
|
{
|
||||||
return mLineEdit->text();
|
QPushButton *okButton = mButtonBox->button(QDialogButtonBox::Ok);
|
||||||
}
|
okButton->setEnabled(enabled);
|
||||||
|
|
||||||
void Launcher::TextInputDialog::slotUpdateOkButton(QString text)
|
QPalette palette;
|
||||||
{
|
palette.setColor(QPalette::Text, Qt::red);
|
||||||
bool enabled = !(text.isEmpty());
|
|
||||||
mButtonBox->button(QDialogButtonBox::Ok)->setEnabled(enabled);
|
|
||||||
|
|
||||||
if (enabled)
|
if (enabled) {
|
||||||
mLineEdit->setPalette(QApplication::palette());
|
mLineEdit->setPalette(QApplication::palette());
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
// Existing profile name, make the text red
|
// Existing profile name, make the text red
|
||||||
QPalette *palette = new QPalette();
|
mLineEdit->setPalette(palette);
|
||||||
palette->setColor(QPalette::Text,Qt::red);
|
|
||||||
mLineEdit->setPalette(*palette);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Launcher::TextInputDialog::DialogLineEdit::DialogLineEdit (QWidget *parent) :
|
|
||||||
LineEdit (parent)
|
|
||||||
{
|
|
||||||
int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
|
|
||||||
|
|
||||||
setObjectName(QString("LineEdit"));
|
|
||||||
setStyleSheet(QString("LineEdit { padding-right: %1px; } ").arg(mClearButton->sizeHint().width() + frameWidth + 1));
|
|
||||||
QSize msz = minimumSizeHint();
|
|
||||||
setMinimumSize(qMax(msz.width(), mClearButton->sizeHint().height() + frameWidth * 2 + 2),
|
|
||||||
qMax(msz.height(), mClearButton->sizeHint().height() + frameWidth * 2 + 2));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -13,26 +13,20 @@ namespace Launcher
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
class DialogLineEdit : public LineEdit
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit DialogLineEdit (QWidget *parent = 0);
|
|
||||||
};
|
|
||||||
|
|
||||||
DialogLineEdit *mLineEdit;
|
|
||||||
QDialogButtonBox *mButtonBox;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
explicit TextInputDialog(const QString& title, const QString &text, QWidget *parent = 0);
|
explicit TextInputDialog(const QString& title, const QString &text, QWidget *parent = 0);
|
||||||
~TextInputDialog () {}
|
~TextInputDialog ();
|
||||||
|
|
||||||
QString getText() const;
|
inline LineEdit *lineEdit() { return mLineEdit; }
|
||||||
|
void setOkButtonEnabled(bool enabled);
|
||||||
|
|
||||||
int exec();
|
int exec();
|
||||||
|
|
||||||
private slots:
|
private:
|
||||||
void slotUpdateOkButton(QString text);
|
|
||||||
|
QDialogButtonBox *mButtonBox;
|
||||||
|
LineEdit *mLineEdit;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ opencs_units (model/doc
|
||||||
)
|
)
|
||||||
|
|
||||||
opencs_units_noqt (model/doc
|
opencs_units_noqt (model/doc
|
||||||
stage savingstate savingstages blacklist
|
stage savingstate savingstages blacklist messages
|
||||||
)
|
)
|
||||||
|
|
||||||
opencs_hdrs_noqt (model/doc
|
opencs_hdrs_noqt (model/doc
|
||||||
|
@ -68,16 +68,17 @@ opencs_units (view/world
|
||||||
|
|
||||||
opencs_units_noqt (view/world
|
opencs_units_noqt (view/world
|
||||||
subviews enumdelegate vartypedelegate recordstatusdelegate idtypedelegate datadisplaydelegate
|
subviews enumdelegate vartypedelegate recordstatusdelegate idtypedelegate datadisplaydelegate
|
||||||
scripthighlighter idvalidator dialoguecreator physicssystem physicsmanager
|
scripthighlighter idvalidator dialoguecreator physicssystem
|
||||||
)
|
)
|
||||||
|
|
||||||
opencs_units (view/widget
|
opencs_units (view/widget
|
||||||
scenetoolbar scenetool scenetoolmode pushbutton scenetooltoggle scenetoolrun
|
scenetoolbar scenetool scenetoolmode pushbutton scenetooltoggle scenetoolrun modebutton
|
||||||
|
scenetooltoggle2
|
||||||
)
|
)
|
||||||
|
|
||||||
opencs_units (view/render
|
opencs_units (view/render
|
||||||
scenewidget worldspacewidget pagedworldspacewidget unpagedworldspacewidget
|
scenewidget worldspacewidget pagedworldspacewidget unpagedworldspacewidget
|
||||||
previewwidget
|
previewwidget editmode
|
||||||
)
|
)
|
||||||
|
|
||||||
opencs_units_noqt (view/render
|
opencs_units_noqt (view/render
|
||||||
|
@ -91,7 +92,7 @@ opencs_hdrs_noqt (view/render
|
||||||
|
|
||||||
|
|
||||||
opencs_units (view/tools
|
opencs_units (view/tools
|
||||||
reportsubview
|
reportsubview reporttable
|
||||||
)
|
)
|
||||||
|
|
||||||
opencs_units_noqt (view/tools
|
opencs_units_noqt (view/tools
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
|
|
||||||
#include "editor.hpp"
|
#include "editor.hpp"
|
||||||
|
|
||||||
|
#include <openengine/bullet/BulletShapeLoader.h>
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QLocalServer>
|
#include <QLocalServer>
|
||||||
#include <QLocalSocket>
|
#include <QLocalSocket>
|
||||||
|
@ -21,8 +23,8 @@
|
||||||
|
|
||||||
CS::Editor::Editor (OgreInit::OgreInit& ogreInit)
|
CS::Editor::Editor (OgreInit::OgreInit& ogreInit)
|
||||||
: mUserSettings (mCfgMgr), mOverlaySystem (0), mDocumentManager (mCfgMgr),
|
: mUserSettings (mCfgMgr), mOverlaySystem (0), mDocumentManager (mCfgMgr),
|
||||||
mViewManager (mDocumentManager), mPhysicsManager (0),
|
mViewManager (mDocumentManager),
|
||||||
mIpcServerName ("org.openmw.OpenCS"), mServer(NULL), mClientSocket(NULL)
|
mIpcServerName ("org.openmw.OpenCS"), mServer(NULL), mClientSocket(NULL), mPid(""), mLock()
|
||||||
{
|
{
|
||||||
std::pair<Files::PathContainer, std::vector<std::string> > config = readConfig();
|
std::pair<Files::PathContainer, std::vector<std::string> > config = readConfig();
|
||||||
|
|
||||||
|
@ -34,7 +36,6 @@ CS::Editor::Editor (OgreInit::OgreInit& ogreInit)
|
||||||
ogreInit.init ((mCfgMgr.getUserConfigPath() / "opencsOgre.log").string());
|
ogreInit.init ((mCfgMgr.getUserConfigPath() / "opencsOgre.log").string());
|
||||||
|
|
||||||
mOverlaySystem.reset (new CSVRender::OverlaySystem);
|
mOverlaySystem.reset (new CSVRender::OverlaySystem);
|
||||||
mPhysicsManager.reset (new CSVWorld::PhysicsManager);
|
|
||||||
|
|
||||||
Bsa::registerResources (Files::Collections (config.first, !mFsStrict), config.second, true,
|
Bsa::registerResources (Files::Collections (config.first, !mFsStrict), config.second, true,
|
||||||
mFsStrict);
|
mFsStrict);
|
||||||
|
@ -70,7 +71,15 @@ CS::Editor::Editor (OgreInit::OgreInit& ogreInit)
|
||||||
}
|
}
|
||||||
|
|
||||||
CS::Editor::~Editor ()
|
CS::Editor::~Editor ()
|
||||||
{}
|
{
|
||||||
|
mPidFile.close();
|
||||||
|
|
||||||
|
if(mServer && boost::filesystem::exists(mPid))
|
||||||
|
remove(mPid.string().c_str()); // ignore any error
|
||||||
|
|
||||||
|
// cleanup global resources used by OEngine
|
||||||
|
delete OEngine::Physic::BulletShapeManager::getSingletonPtr();
|
||||||
|
}
|
||||||
|
|
||||||
void CS::Editor::setupDataFiles (const Files::PathContainer& dataDirs)
|
void CS::Editor::setupDataFiles (const Files::PathContainer& dataDirs)
|
||||||
{
|
{
|
||||||
|
@ -233,8 +242,54 @@ void CS::Editor::showSettings()
|
||||||
|
|
||||||
bool CS::Editor::makeIPCServer()
|
bool CS::Editor::makeIPCServer()
|
||||||
{
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
mPid = boost::filesystem::temp_directory_path();
|
||||||
|
mPid /= "opencs.pid";
|
||||||
|
bool pidExists = boost::filesystem::exists(mPid);
|
||||||
|
|
||||||
|
mPidFile.open(mPid);
|
||||||
|
|
||||||
|
mLock = boost::interprocess::file_lock(mPid.string().c_str());
|
||||||
|
if(!mLock.try_lock())
|
||||||
|
{
|
||||||
|
std::cerr << "OpenCS already running." << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
mPidFile << GetCurrentProcessId() << std::endl;
|
||||||
|
#else
|
||||||
|
mPidFile << getpid() << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
mServer = new QLocalServer(this);
|
mServer = new QLocalServer(this);
|
||||||
|
|
||||||
|
if(pidExists)
|
||||||
|
{
|
||||||
|
// hack to get the temp directory path
|
||||||
|
mServer->listen("dummy");
|
||||||
|
QString fullPath = mServer->fullServerName();
|
||||||
|
mServer->close();
|
||||||
|
fullPath.remove(QRegExp("dummy$"));
|
||||||
|
fullPath += mIpcServerName;
|
||||||
|
if(boost::filesystem::exists(fullPath.toStdString().c_str()))
|
||||||
|
{
|
||||||
|
// TODO: compare pid of the current process with that in the file
|
||||||
|
std::cout << "Detected unclean shutdown." << std::endl;
|
||||||
|
// delete the stale file
|
||||||
|
if(remove(fullPath.toStdString().c_str()))
|
||||||
|
std::cerr << "ERROR removing stale connection file" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
catch(const std::exception& e)
|
||||||
|
{
|
||||||
|
std::cerr << "ERROR " << e.what() << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if(mServer->listen(mIpcServerName))
|
if(mServer->listen(mIpcServerName))
|
||||||
{
|
{
|
||||||
connect(mServer, SIGNAL(newConnection()), this, SLOT(showStartup()));
|
connect(mServer, SIGNAL(newConnection()), this, SLOT(showStartup()));
|
||||||
|
@ -242,6 +297,7 @@ bool CS::Editor::makeIPCServer()
|
||||||
}
|
}
|
||||||
|
|
||||||
mServer->close();
|
mServer->close();
|
||||||
|
mServer = NULL;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -379,5 +435,5 @@ void CS::Editor::documentAdded (CSMDoc::Document *document)
|
||||||
|
|
||||||
void CS::Editor::lastDocumentDeleted()
|
void CS::Editor::lastDocumentDeleted()
|
||||||
{
|
{
|
||||||
exit (0);
|
QApplication::quit();
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,9 @@
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
#include <boost/interprocess/sync/file_lock.hpp>
|
||||||
|
#include <boost/filesystem/fstream.hpp>
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QLocalServer>
|
#include <QLocalServer>
|
||||||
|
@ -28,7 +31,6 @@
|
||||||
|
|
||||||
#include "view/settings/dialog.hpp"
|
#include "view/settings/dialog.hpp"
|
||||||
#include "view/render/overlaysystem.hpp"
|
#include "view/render/overlaysystem.hpp"
|
||||||
#include "view/world/physicsmanager.hpp"
|
|
||||||
|
|
||||||
namespace OgreInit
|
namespace OgreInit
|
||||||
{
|
{
|
||||||
|
@ -45,7 +47,6 @@ namespace CS
|
||||||
Files::ConfigurationManager mCfgMgr;
|
Files::ConfigurationManager mCfgMgr;
|
||||||
CSMSettings::UserSettings mUserSettings;
|
CSMSettings::UserSettings mUserSettings;
|
||||||
std::auto_ptr<CSVRender::OverlaySystem> mOverlaySystem;
|
std::auto_ptr<CSVRender::OverlaySystem> mOverlaySystem;
|
||||||
std::auto_ptr<CSVWorld::PhysicsManager> mPhysicsManager;
|
|
||||||
CSMDoc::DocumentManager mDocumentManager;
|
CSMDoc::DocumentManager mDocumentManager;
|
||||||
CSVDoc::ViewManager mViewManager;
|
CSVDoc::ViewManager mViewManager;
|
||||||
CSVDoc::StartupDialogue mStartup;
|
CSVDoc::StartupDialogue mStartup;
|
||||||
|
@ -54,6 +55,9 @@ namespace CS
|
||||||
CSVDoc::FileDialog mFileDialog;
|
CSVDoc::FileDialog mFileDialog;
|
||||||
boost::filesystem::path mLocal;
|
boost::filesystem::path mLocal;
|
||||||
boost::filesystem::path mResources;
|
boost::filesystem::path mResources;
|
||||||
|
boost::filesystem::path mPid;
|
||||||
|
boost::interprocess::file_lock mLock;
|
||||||
|
boost::filesystem::ofstream mPidFile;
|
||||||
bool mFsStrict;
|
bool mFsStrict;
|
||||||
|
|
||||||
void setupDataFiles (const Files::PathContainer& dataDirs);
|
void setupDataFiles (const Files::PathContainer& dataDirs);
|
||||||
|
|
|
@ -83,7 +83,7 @@ int main(int argc, char *argv[])
|
||||||
if(!editor.makeIPCServer())
|
if(!editor.makeIPCServer())
|
||||||
{
|
{
|
||||||
editor.connectToIPCServer();
|
editor.connectToIPCServer();
|
||||||
// return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
shinyFactory = editor.setupGraphics();
|
shinyFactory = editor.setupGraphics();
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
#include <components/files/configurationmanager.hpp>
|
#include <components/files/configurationmanager.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "../../view/world/physicssystem.hpp"
|
||||||
|
|
||||||
void CSMDoc::Document::addGmsts()
|
void CSMDoc::Document::addGmsts()
|
||||||
{
|
{
|
||||||
static const char *gmstFloats[] =
|
static const char *gmstFloats[] =
|
||||||
|
@ -2253,7 +2255,7 @@ CSMDoc::Document::Document (const Files::ConfigurationManager& configuration,
|
||||||
mProjectPath ((configuration.getUserDataPath() / "projects") /
|
mProjectPath ((configuration.getUserDataPath() / "projects") /
|
||||||
(savePath.filename().string() + ".project")),
|
(savePath.filename().string() + ".project")),
|
||||||
mSaving (*this, mProjectPath, encoding),
|
mSaving (*this, mProjectPath, encoding),
|
||||||
mRunner (mProjectPath)
|
mRunner (mProjectPath), mPhysics(boost::shared_ptr<CSVWorld::PhysicsSystem>())
|
||||||
{
|
{
|
||||||
if (mContentFiles.empty())
|
if (mContentFiles.empty())
|
||||||
throw std::runtime_error ("Empty content file sequence");
|
throw std::runtime_error ("Empty content file sequence");
|
||||||
|
@ -2299,8 +2301,8 @@ CSMDoc::Document::Document (const Files::ConfigurationManager& configuration,
|
||||||
connect (&mSaving, SIGNAL (done (int, bool)), this, SLOT (operationDone (int, bool)));
|
connect (&mSaving, SIGNAL (done (int, bool)), this, SLOT (operationDone (int, bool)));
|
||||||
|
|
||||||
connect (
|
connect (
|
||||||
&mSaving, SIGNAL (reportMessage (const CSMWorld::UniversalId&, const std::string&, int)),
|
&mSaving, SIGNAL (reportMessage (const CSMWorld::UniversalId&, const std::string&, const std::string&, int)),
|
||||||
this, SLOT (reportMessage (const CSMWorld::UniversalId&, const std::string&, int)));
|
this, SLOT (reportMessage (const CSMWorld::UniversalId&, const std::string&, const std::string&, int)));
|
||||||
|
|
||||||
connect (&mRunner, SIGNAL (runStateChanged()), this, SLOT (runStateChanged()));
|
connect (&mRunner, SIGNAL (runStateChanged()), this, SLOT (runStateChanged()));
|
||||||
}
|
}
|
||||||
|
@ -2385,7 +2387,7 @@ void CSMDoc::Document::modificationStateChanged (bool clean)
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSMDoc::Document::reportMessage (const CSMWorld::UniversalId& id, const std::string& message,
|
void CSMDoc::Document::reportMessage (const CSMWorld::UniversalId& id, const std::string& message,
|
||||||
int type)
|
const std::string& hint, int type)
|
||||||
{
|
{
|
||||||
/// \todo find a better way to get these messages to the user.
|
/// \todo find a better way to get these messages to the user.
|
||||||
std::cout << message << std::endl;
|
std::cout << message << std::endl;
|
||||||
|
@ -2464,3 +2466,11 @@ void CSMDoc::Document::progress (int current, int max, int type)
|
||||||
{
|
{
|
||||||
emit progress (current, max, type, 1, this);
|
emit progress (current, max, type, 1, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boost::shared_ptr<CSVWorld::PhysicsSystem> CSMDoc::Document::getPhysics ()
|
||||||
|
{
|
||||||
|
if(!mPhysics)
|
||||||
|
mPhysics = boost::shared_ptr<CSVWorld::PhysicsSystem> (new CSVWorld::PhysicsSystem());
|
||||||
|
|
||||||
|
return mPhysics;
|
||||||
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
#include <boost/filesystem/path.hpp>
|
#include <boost/filesystem/path.hpp>
|
||||||
|
|
||||||
#include <QUndoStack>
|
#include <QUndoStack>
|
||||||
|
@ -39,6 +40,11 @@ namespace CSMWorld
|
||||||
class ResourcesManager;
|
class ResourcesManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace CSVWorld
|
||||||
|
{
|
||||||
|
class PhysicsSystem;
|
||||||
|
}
|
||||||
|
|
||||||
namespace CSMDoc
|
namespace CSMDoc
|
||||||
{
|
{
|
||||||
class Document : public QObject
|
class Document : public QObject
|
||||||
|
@ -57,6 +63,7 @@ namespace CSMDoc
|
||||||
boost::filesystem::path mResDir;
|
boost::filesystem::path mResDir;
|
||||||
Blacklist mBlacklist;
|
Blacklist mBlacklist;
|
||||||
Runner mRunner;
|
Runner mRunner;
|
||||||
|
boost::shared_ptr<CSVWorld::PhysicsSystem> mPhysics;
|
||||||
|
|
||||||
// It is important that the undo stack is declared last, because on desctruction it fires a signal, that is connected to a slot, that is
|
// It is important that the undo stack is declared last, because on desctruction it fires a signal, that is connected to a slot, that is
|
||||||
// using other member variables. Unfortunately this connection is cut only in the QObject destructor, which is way too late.
|
// using other member variables. Unfortunately this connection is cut only in the QObject destructor, which is way too late.
|
||||||
|
@ -129,6 +136,8 @@ namespace CSMDoc
|
||||||
|
|
||||||
QTextDocument *getRunLog();
|
QTextDocument *getRunLog();
|
||||||
|
|
||||||
|
boost::shared_ptr<CSVWorld::PhysicsSystem> getPhysics();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
void stateChanged (int state, CSMDoc::Document *document);
|
void stateChanged (int state, CSMDoc::Document *document);
|
||||||
|
@ -140,7 +149,7 @@ namespace CSMDoc
|
||||||
void modificationStateChanged (bool clean);
|
void modificationStateChanged (bool clean);
|
||||||
|
|
||||||
void reportMessage (const CSMWorld::UniversalId& id, const std::string& message,
|
void reportMessage (const CSMWorld::UniversalId& id, const std::string& message,
|
||||||
int type);
|
const std::string& hint, int type);
|
||||||
|
|
||||||
void operationDone (int type, bool failed);
|
void operationDone (int type, bool failed);
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,7 @@ void CSMDoc::Loader::load()
|
||||||
{
|
{
|
||||||
if (iter->second.mRecordsLeft)
|
if (iter->second.mRecordsLeft)
|
||||||
{
|
{
|
||||||
CSMDoc::Stage::Messages messages;
|
CSMDoc::Messages messages;
|
||||||
for (int i=0; i<batchingSize; ++i) // do not flood the system with update signals
|
for (int i=0; i<batchingSize; ++i) // do not flood the system with update signals
|
||||||
if (document->getData().continueLoading (messages))
|
if (document->getData().continueLoading (messages))
|
||||||
{
|
{
|
||||||
|
@ -65,11 +65,11 @@ void CSMDoc::Loader::load()
|
||||||
CSMWorld::UniversalId log (CSMWorld::UniversalId::Type_LoadErrorLog, 0);
|
CSMWorld::UniversalId log (CSMWorld::UniversalId::Type_LoadErrorLog, 0);
|
||||||
|
|
||||||
{ // silence a g++ warning
|
{ // silence a g++ warning
|
||||||
for (CSMDoc::Stage::Messages::const_iterator iter (messages.begin());
|
for (CSMDoc::Messages::Iterator iter (messages.begin());
|
||||||
iter!=messages.end(); ++iter)
|
iter!=messages.end(); ++iter)
|
||||||
{
|
{
|
||||||
document->getReport (log)->add (iter->first, iter->second);
|
document->getReport (log)->add (iter->mId, iter->mMessage);
|
||||||
emit loadMessage (document, iter->second);
|
emit loadMessage (document, iter->mMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
28
apps/opencs/model/doc/messages.cpp
Normal file
28
apps/opencs/model/doc/messages.cpp
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
|
||||||
|
#include "messages.hpp"
|
||||||
|
|
||||||
|
void CSMDoc::Messages::add (const CSMWorld::UniversalId& id, const std::string& message,
|
||||||
|
const std::string& hint)
|
||||||
|
{
|
||||||
|
Message data;
|
||||||
|
data.mId = id;
|
||||||
|
data.mMessage = message;
|
||||||
|
data.mHint = hint;
|
||||||
|
|
||||||
|
mMessages.push_back (data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMDoc::Messages::push_back (const std::pair<CSMWorld::UniversalId, std::string>& data)
|
||||||
|
{
|
||||||
|
add (data.first, data.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
CSMDoc::Messages::Iterator CSMDoc::Messages::begin() const
|
||||||
|
{
|
||||||
|
return mMessages.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
CSMDoc::Messages::Iterator CSMDoc::Messages::end() const
|
||||||
|
{
|
||||||
|
return mMessages.end();
|
||||||
|
}
|
44
apps/opencs/model/doc/messages.hpp
Normal file
44
apps/opencs/model/doc/messages.hpp
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
#ifndef CSM_DOC_MESSAGES_H
|
||||||
|
#define CSM_DOC_MESSAGES_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "../world/universalid.hpp"
|
||||||
|
|
||||||
|
namespace CSMDoc
|
||||||
|
{
|
||||||
|
class Messages
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
struct Message
|
||||||
|
{
|
||||||
|
CSMWorld::UniversalId mId;
|
||||||
|
std::string mMessage;
|
||||||
|
std::string mHint;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::vector<Message> Collection;
|
||||||
|
|
||||||
|
typedef Collection::const_iterator Iterator;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
Collection mMessages;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
void add (const CSMWorld::UniversalId& id, const std::string& message,
|
||||||
|
const std::string& hint = "");
|
||||||
|
|
||||||
|
/// \deprecated Use add instead.
|
||||||
|
void push_back (const std::pair<CSMWorld::UniversalId, std::string>& data);
|
||||||
|
|
||||||
|
Iterator begin() const;
|
||||||
|
|
||||||
|
Iterator end() const;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -84,7 +84,7 @@ void CSMDoc::Operation::abort()
|
||||||
|
|
||||||
void CSMDoc::Operation::executeStage()
|
void CSMDoc::Operation::executeStage()
|
||||||
{
|
{
|
||||||
Stage::Messages messages;
|
Messages messages;
|
||||||
|
|
||||||
while (mCurrentStage!=mStages.end())
|
while (mCurrentStage!=mStages.end())
|
||||||
{
|
{
|
||||||
|
@ -101,7 +101,7 @@ void CSMDoc::Operation::executeStage()
|
||||||
}
|
}
|
||||||
catch (const std::exception& e)
|
catch (const std::exception& e)
|
||||||
{
|
{
|
||||||
emit reportMessage (CSMWorld::UniversalId(), e.what(), mType);
|
emit reportMessage (CSMWorld::UniversalId(), e.what(), "", mType);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,8 +112,8 @@ void CSMDoc::Operation::executeStage()
|
||||||
|
|
||||||
emit progress (mCurrentStepTotal, mTotalSteps ? mTotalSteps : 1, mType);
|
emit progress (mCurrentStepTotal, mTotalSteps ? mTotalSteps : 1, mType);
|
||||||
|
|
||||||
for (Stage::Messages::const_iterator iter (messages.begin()); iter!=messages.end(); ++iter)
|
for (Messages::Iterator iter (messages.begin()); iter!=messages.end(); ++iter)
|
||||||
emit reportMessage (iter->first, iter->second, mType);
|
emit reportMessage (iter->mId, iter->mMessage, iter->mHint, mType);
|
||||||
|
|
||||||
if (mCurrentStage==mStages.end())
|
if (mCurrentStage==mStages.end())
|
||||||
exit();
|
exit();
|
||||||
|
|
|
@ -52,7 +52,7 @@ namespace CSMDoc
|
||||||
void progress (int current, int max, int type);
|
void progress (int current, int max, int type);
|
||||||
|
|
||||||
void reportMessage (const CSMWorld::UniversalId& id, const std::string& message,
|
void reportMessage (const CSMWorld::UniversalId& id, const std::string& message,
|
||||||
int type);
|
const std::string& hint, int type);
|
||||||
|
|
||||||
void done (int type, bool failed);
|
void done (int type, bool failed);
|
||||||
|
|
||||||
|
|
|
@ -6,14 +6,14 @@
|
||||||
|
|
||||||
#include "../world/universalid.hpp"
|
#include "../world/universalid.hpp"
|
||||||
|
|
||||||
|
#include "messages.hpp"
|
||||||
|
|
||||||
namespace CSMDoc
|
namespace CSMDoc
|
||||||
{
|
{
|
||||||
class Stage
|
class Stage
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
typedef std::vector<std::pair<CSMWorld::UniversalId, std::string> > Messages;
|
|
||||||
|
|
||||||
virtual ~Stage();
|
virtual ~Stage();
|
||||||
|
|
||||||
virtual int setup() = 0;
|
virtual int setup() = 0;
|
||||||
|
|
|
@ -17,7 +17,7 @@ int CSMTools::BirthsignCheckStage::setup()
|
||||||
return mBirthsigns.getSize();
|
return mBirthsigns.getSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSMTools::BirthsignCheckStage::perform (int stage, Messages& messages)
|
void CSMTools::BirthsignCheckStage::perform (int stage, CSMDoc::Messages& messages)
|
||||||
{
|
{
|
||||||
const CSMWorld::Record<ESM::BirthSign>& record = mBirthsigns.getRecord (stage);
|
const CSMWorld::Record<ESM::BirthSign>& record = mBirthsigns.getRecord (stage);
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ namespace CSMTools
|
||||||
virtual int setup();
|
virtual int setup();
|
||||||
///< \return number of steps
|
///< \return number of steps
|
||||||
|
|
||||||
virtual void perform (int stage, Messages& messages);
|
virtual void perform (int stage, CSMDoc::Messages& messages);
|
||||||
///< Messages resulting from this tage will be appended to \a messages.
|
///< Messages resulting from this tage will be appended to \a messages.
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ int CSMTools::BodyPartCheckStage::setup()
|
||||||
return mBodyParts.getSize();
|
return mBodyParts.getSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSMTools::BodyPartCheckStage::perform ( int stage, Messages &messages )
|
void CSMTools::BodyPartCheckStage::perform (int stage, CSMDoc::Messages &messages)
|
||||||
{
|
{
|
||||||
const CSMWorld::Record<ESM::BodyPart> &record = mBodyParts.getRecord(stage);
|
const CSMWorld::Record<ESM::BodyPart> &record = mBodyParts.getRecord(stage);
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ namespace CSMTools
|
||||||
virtual int setup();
|
virtual int setup();
|
||||||
///< \return number of steps
|
///< \return number of steps
|
||||||
|
|
||||||
virtual void perform( int stage, Messages &messages );
|
virtual void perform( int stage, CSMDoc::Messages &messages );
|
||||||
///< Messages resulting from this tage will be appended to \a messages.
|
///< Messages resulting from this tage will be appended to \a messages.
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ int CSMTools::ClassCheckStage::setup()
|
||||||
return mClasses.getSize();
|
return mClasses.getSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSMTools::ClassCheckStage::perform (int stage, Messages& messages)
|
void CSMTools::ClassCheckStage::perform (int stage, CSMDoc::Messages& messages)
|
||||||
{
|
{
|
||||||
const CSMWorld::Record<ESM::Class>& record = mClasses.getRecord (stage);
|
const CSMWorld::Record<ESM::Class>& record = mClasses.getRecord (stage);
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ namespace CSMTools
|
||||||
virtual int setup();
|
virtual int setup();
|
||||||
///< \return number of steps
|
///< \return number of steps
|
||||||
|
|
||||||
virtual void perform (int stage, Messages& messages);
|
virtual void perform (int stage, CSMDoc::Messages& messages);
|
||||||
///< Messages resulting from this tage will be appended to \a messages.
|
///< Messages resulting from this tage will be appended to \a messages.
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ int CSMTools::FactionCheckStage::setup()
|
||||||
return mFactions.getSize();
|
return mFactions.getSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSMTools::FactionCheckStage::perform (int stage, Messages& messages)
|
void CSMTools::FactionCheckStage::perform (int stage, CSMDoc::Messages& messages)
|
||||||
{
|
{
|
||||||
const CSMWorld::Record<ESM::Faction>& record = mFactions.getRecord (stage);
|
const CSMWorld::Record<ESM::Faction>& record = mFactions.getRecord (stage);
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ namespace CSMTools
|
||||||
virtual int setup();
|
virtual int setup();
|
||||||
///< \return number of steps
|
///< \return number of steps
|
||||||
|
|
||||||
virtual void perform (int stage, Messages& messages);
|
virtual void perform (int stage, CSMDoc::Messages& messages);
|
||||||
///< Messages resulting from this tage will be appended to \a messages.
|
///< Messages resulting from this tage will be appended to \a messages.
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,10 +15,9 @@ int CSMTools::MandatoryIdStage::setup()
|
||||||
return mIds.size();
|
return mIds.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSMTools::MandatoryIdStage::perform (int stage, Messages& messages)
|
void CSMTools::MandatoryIdStage::perform (int stage, CSMDoc::Messages& messages)
|
||||||
{
|
{
|
||||||
if (mIdCollection.searchId (mIds.at (stage))==-1 ||
|
if (mIdCollection.searchId (mIds.at (stage))==-1 ||
|
||||||
mIdCollection.getRecord (mIds.at (stage)).isDeleted())
|
mIdCollection.getRecord (mIds.at (stage)).isDeleted())
|
||||||
messages.push_back (std::make_pair (mCollectionId,
|
messages.add (mCollectionId, "Missing mandatory record: " + mIds.at (stage));
|
||||||
"Missing mandatory record: " + mIds.at (stage)));
|
|
||||||
}
|
}
|
|
@ -30,7 +30,7 @@ namespace CSMTools
|
||||||
virtual int setup();
|
virtual int setup();
|
||||||
///< \return number of steps
|
///< \return number of steps
|
||||||
|
|
||||||
virtual void perform (int stage, Messages& messages);
|
virtual void perform (int stage, CSMDoc::Messages& messages);
|
||||||
///< Messages resulting from this tage will be appended to \a messages.
|
///< Messages resulting from this tage will be appended to \a messages.
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
#include "../world/universalid.hpp"
|
#include "../world/universalid.hpp"
|
||||||
|
|
||||||
void CSMTools::RaceCheckStage::performPerRecord (int stage, Messages& messages)
|
void CSMTools::RaceCheckStage::performPerRecord (int stage, CSMDoc::Messages& messages)
|
||||||
{
|
{
|
||||||
const CSMWorld::Record<ESM::Race>& record = mRaces.getRecord (stage);
|
const CSMWorld::Record<ESM::Race>& record = mRaces.getRecord (stage);
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ void CSMTools::RaceCheckStage::performPerRecord (int stage, Messages& messages)
|
||||||
/// \todo check data members that can't be edited in the table view
|
/// \todo check data members that can't be edited in the table view
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSMTools::RaceCheckStage::performFinal (Messages& messages)
|
void CSMTools::RaceCheckStage::performFinal (CSMDoc::Messages& messages)
|
||||||
{
|
{
|
||||||
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Races);
|
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Races);
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ int CSMTools::RaceCheckStage::setup()
|
||||||
return mRaces.getSize()+1;
|
return mRaces.getSize()+1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSMTools::RaceCheckStage::perform (int stage, Messages& messages)
|
void CSMTools::RaceCheckStage::perform (int stage, CSMDoc::Messages& messages)
|
||||||
{
|
{
|
||||||
if (stage==mRaces.getSize())
|
if (stage==mRaces.getSize())
|
||||||
performFinal (messages);
|
performFinal (messages);
|
||||||
|
|
|
@ -15,9 +15,9 @@ namespace CSMTools
|
||||||
const CSMWorld::IdCollection<ESM::Race>& mRaces;
|
const CSMWorld::IdCollection<ESM::Race>& mRaces;
|
||||||
bool mPlayable;
|
bool mPlayable;
|
||||||
|
|
||||||
void performPerRecord (int stage, Messages& messages);
|
void performPerRecord (int stage, CSMDoc::Messages& messages);
|
||||||
|
|
||||||
void performFinal (Messages& messages);
|
void performFinal (CSMDoc::Messages& messages);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ namespace CSMTools
|
||||||
virtual int setup();
|
virtual int setup();
|
||||||
///< \return number of steps
|
///< \return number of steps
|
||||||
|
|
||||||
virtual void perform (int stage, Messages& messages);
|
virtual void perform (int stage, CSMDoc::Messages& messages);
|
||||||
///< Messages resulting from this tage will be appended to \a messages.
|
///< Messages resulting from this tage will be appended to \a messages.
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ CSMTools::ReferenceableCheckStage::ReferenceableCheckStage(
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSMTools::ReferenceableCheckStage::perform (int stage, Messages& messages)
|
void CSMTools::ReferenceableCheckStage::perform (int stage, CSMDoc::Messages& messages)
|
||||||
{
|
{
|
||||||
//Checks for books, than, when stage is above mBooksSize goes to other checks, with (stage - PrevSum) as stage.
|
//Checks for books, than, when stage is above mBooksSize goes to other checks, with (stage - PrevSum) as stage.
|
||||||
const int bookSize(mReferencables.getBooks().getSize());
|
const int bookSize(mReferencables.getBooks().getSize());
|
||||||
|
@ -232,7 +232,7 @@ int CSMTools::ReferenceableCheckStage::setup()
|
||||||
void CSMTools::ReferenceableCheckStage::bookCheck(
|
void CSMTools::ReferenceableCheckStage::bookCheck(
|
||||||
int stage,
|
int stage,
|
||||||
const CSMWorld::RefIdDataContainer< ESM::Book >& records,
|
const CSMWorld::RefIdDataContainer< ESM::Book >& records,
|
||||||
Messages& messages)
|
CSMDoc::Messages& messages)
|
||||||
{
|
{
|
||||||
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
||||||
|
|
||||||
|
@ -250,7 +250,7 @@ void CSMTools::ReferenceableCheckStage::bookCheck(
|
||||||
void CSMTools::ReferenceableCheckStage::activatorCheck(
|
void CSMTools::ReferenceableCheckStage::activatorCheck(
|
||||||
int stage,
|
int stage,
|
||||||
const CSMWorld::RefIdDataContainer< ESM::Activator >& records,
|
const CSMWorld::RefIdDataContainer< ESM::Activator >& records,
|
||||||
Messages& messages)
|
CSMDoc::Messages& messages)
|
||||||
{
|
{
|
||||||
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
||||||
|
|
||||||
|
@ -270,7 +270,7 @@ void CSMTools::ReferenceableCheckStage::activatorCheck(
|
||||||
void CSMTools::ReferenceableCheckStage::potionCheck(
|
void CSMTools::ReferenceableCheckStage::potionCheck(
|
||||||
int stage,
|
int stage,
|
||||||
const CSMWorld::RefIdDataContainer< ESM::Potion >& records,
|
const CSMWorld::RefIdDataContainer< ESM::Potion >& records,
|
||||||
Messages& messages)
|
CSMDoc::Messages& messages)
|
||||||
{
|
{
|
||||||
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
||||||
|
|
||||||
|
@ -290,7 +290,7 @@ void CSMTools::ReferenceableCheckStage::potionCheck(
|
||||||
void CSMTools::ReferenceableCheckStage::apparatusCheck(
|
void CSMTools::ReferenceableCheckStage::apparatusCheck(
|
||||||
int stage,
|
int stage,
|
||||||
const CSMWorld::RefIdDataContainer< ESM::Apparatus >& records,
|
const CSMWorld::RefIdDataContainer< ESM::Apparatus >& records,
|
||||||
Messages& messages)
|
CSMDoc::Messages& messages)
|
||||||
{
|
{
|
||||||
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
||||||
|
|
||||||
|
@ -310,7 +310,7 @@ void CSMTools::ReferenceableCheckStage::apparatusCheck(
|
||||||
void CSMTools::ReferenceableCheckStage::armorCheck(
|
void CSMTools::ReferenceableCheckStage::armorCheck(
|
||||||
int stage,
|
int stage,
|
||||||
const CSMWorld::RefIdDataContainer< ESM::Armor >& records,
|
const CSMWorld::RefIdDataContainer< ESM::Armor >& records,
|
||||||
Messages& messages)
|
CSMDoc::Messages& messages)
|
||||||
{
|
{
|
||||||
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
||||||
|
|
||||||
|
@ -336,7 +336,7 @@ void CSMTools::ReferenceableCheckStage::armorCheck(
|
||||||
void CSMTools::ReferenceableCheckStage::clothingCheck(
|
void CSMTools::ReferenceableCheckStage::clothingCheck(
|
||||||
int stage,
|
int stage,
|
||||||
const CSMWorld::RefIdDataContainer< ESM::Clothing >& records,
|
const CSMWorld::RefIdDataContainer< ESM::Clothing >& records,
|
||||||
Messages& messages)
|
CSMDoc::Messages& messages)
|
||||||
{
|
{
|
||||||
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
||||||
|
|
||||||
|
@ -353,7 +353,7 @@ void CSMTools::ReferenceableCheckStage::clothingCheck(
|
||||||
void CSMTools::ReferenceableCheckStage::containerCheck(
|
void CSMTools::ReferenceableCheckStage::containerCheck(
|
||||||
int stage,
|
int stage,
|
||||||
const CSMWorld::RefIdDataContainer< ESM::Container >& records,
|
const CSMWorld::RefIdDataContainer< ESM::Container >& records,
|
||||||
Messages& messages)
|
CSMDoc::Messages& messages)
|
||||||
{
|
{
|
||||||
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
||||||
|
|
||||||
|
@ -381,7 +381,7 @@ void CSMTools::ReferenceableCheckStage::containerCheck(
|
||||||
|
|
||||||
void CSMTools::ReferenceableCheckStage::creatureCheck (
|
void CSMTools::ReferenceableCheckStage::creatureCheck (
|
||||||
int stage, const CSMWorld::RefIdDataContainer< ESM::Creature >& records,
|
int stage, const CSMWorld::RefIdDataContainer< ESM::Creature >& records,
|
||||||
Messages& messages)
|
CSMDoc::Messages& messages)
|
||||||
{
|
{
|
||||||
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
||||||
|
|
||||||
|
@ -448,7 +448,7 @@ void CSMTools::ReferenceableCheckStage::creatureCheck (
|
||||||
|
|
||||||
void CSMTools::ReferenceableCheckStage::doorCheck(
|
void CSMTools::ReferenceableCheckStage::doorCheck(
|
||||||
int stage, const CSMWorld::RefIdDataContainer< ESM::Door >& records,
|
int stage, const CSMWorld::RefIdDataContainer< ESM::Door >& records,
|
||||||
Messages& messages)
|
CSMDoc::Messages& messages)
|
||||||
{
|
{
|
||||||
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
||||||
|
|
||||||
|
@ -469,7 +469,7 @@ void CSMTools::ReferenceableCheckStage::doorCheck(
|
||||||
void CSMTools::ReferenceableCheckStage::ingredientCheck(
|
void CSMTools::ReferenceableCheckStage::ingredientCheck(
|
||||||
int stage,
|
int stage,
|
||||||
const CSMWorld::RefIdDataContainer< ESM::Ingredient >& records,
|
const CSMWorld::RefIdDataContainer< ESM::Ingredient >& records,
|
||||||
Messages& messages)
|
CSMDoc::Messages& messages)
|
||||||
{
|
{
|
||||||
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
||||||
|
|
||||||
|
@ -487,7 +487,7 @@ void CSMTools::ReferenceableCheckStage::ingredientCheck(
|
||||||
void CSMTools::ReferenceableCheckStage::creaturesLevListCheck(
|
void CSMTools::ReferenceableCheckStage::creaturesLevListCheck(
|
||||||
int stage,
|
int stage,
|
||||||
const CSMWorld::RefIdDataContainer< ESM::CreatureLevList >& records,
|
const CSMWorld::RefIdDataContainer< ESM::CreatureLevList >& records,
|
||||||
Messages& messages)
|
CSMDoc::Messages& messages)
|
||||||
{
|
{
|
||||||
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
||||||
|
|
||||||
|
@ -505,7 +505,7 @@ void CSMTools::ReferenceableCheckStage::creaturesLevListCheck(
|
||||||
void CSMTools::ReferenceableCheckStage::itemLevelledListCheck(
|
void CSMTools::ReferenceableCheckStage::itemLevelledListCheck(
|
||||||
int stage,
|
int stage,
|
||||||
const CSMWorld::RefIdDataContainer< ESM::ItemLevList >& records,
|
const CSMWorld::RefIdDataContainer< ESM::ItemLevList >& records,
|
||||||
Messages& messages)
|
CSMDoc::Messages& messages)
|
||||||
{
|
{
|
||||||
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
||||||
|
|
||||||
|
@ -522,7 +522,7 @@ void CSMTools::ReferenceableCheckStage::itemLevelledListCheck(
|
||||||
|
|
||||||
void CSMTools::ReferenceableCheckStage::lightCheck(
|
void CSMTools::ReferenceableCheckStage::lightCheck(
|
||||||
int stage, const CSMWorld::RefIdDataContainer< ESM::Light >& records,
|
int stage, const CSMWorld::RefIdDataContainer< ESM::Light >& records,
|
||||||
Messages& messages)
|
CSMDoc::Messages& messages)
|
||||||
{
|
{
|
||||||
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
||||||
|
|
||||||
|
@ -547,7 +547,7 @@ void CSMTools::ReferenceableCheckStage::lightCheck(
|
||||||
void CSMTools::ReferenceableCheckStage::lockpickCheck(
|
void CSMTools::ReferenceableCheckStage::lockpickCheck(
|
||||||
int stage,
|
int stage,
|
||||||
const CSMWorld::RefIdDataContainer< ESM::Lockpick >& records,
|
const CSMWorld::RefIdDataContainer< ESM::Lockpick >& records,
|
||||||
Messages& messages)
|
CSMDoc::Messages& messages)
|
||||||
{
|
{
|
||||||
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
||||||
|
|
||||||
|
@ -567,7 +567,7 @@ void CSMTools::ReferenceableCheckStage::lockpickCheck(
|
||||||
void CSMTools::ReferenceableCheckStage::miscCheck(
|
void CSMTools::ReferenceableCheckStage::miscCheck(
|
||||||
int stage,
|
int stage,
|
||||||
const CSMWorld::RefIdDataContainer< ESM::Miscellaneous >& records,
|
const CSMWorld::RefIdDataContainer< ESM::Miscellaneous >& records,
|
||||||
Messages& messages)
|
CSMDoc::Messages& messages)
|
||||||
{
|
{
|
||||||
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
||||||
|
|
||||||
|
@ -584,7 +584,7 @@ void CSMTools::ReferenceableCheckStage::miscCheck(
|
||||||
|
|
||||||
void CSMTools::ReferenceableCheckStage::npcCheck (
|
void CSMTools::ReferenceableCheckStage::npcCheck (
|
||||||
int stage, const CSMWorld::RefIdDataContainer< ESM::NPC >& records,
|
int stage, const CSMWorld::RefIdDataContainer< ESM::NPC >& records,
|
||||||
Messages& messages)
|
CSMDoc::Messages& messages)
|
||||||
{
|
{
|
||||||
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
||||||
|
|
||||||
|
@ -701,7 +701,7 @@ void CSMTools::ReferenceableCheckStage::npcCheck (
|
||||||
|
|
||||||
void CSMTools::ReferenceableCheckStage::weaponCheck(
|
void CSMTools::ReferenceableCheckStage::weaponCheck(
|
||||||
int stage, const CSMWorld::RefIdDataContainer< ESM::Weapon >& records,
|
int stage, const CSMWorld::RefIdDataContainer< ESM::Weapon >& records,
|
||||||
Messages& messages)
|
CSMDoc::Messages& messages)
|
||||||
{
|
{
|
||||||
const CSMWorld::RecordBase& baseRecord = records.getRecord (stage);
|
const CSMWorld::RecordBase& baseRecord = records.getRecord (stage);
|
||||||
|
|
||||||
|
@ -778,7 +778,7 @@ void CSMTools::ReferenceableCheckStage::weaponCheck(
|
||||||
void CSMTools::ReferenceableCheckStage::probeCheck(
|
void CSMTools::ReferenceableCheckStage::probeCheck(
|
||||||
int stage,
|
int stage,
|
||||||
const CSMWorld::RefIdDataContainer< ESM::Probe >& records,
|
const CSMWorld::RefIdDataContainer< ESM::Probe >& records,
|
||||||
Messages& messages)
|
CSMDoc::Messages& messages)
|
||||||
{
|
{
|
||||||
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
||||||
|
|
||||||
|
@ -796,7 +796,7 @@ void CSMTools::ReferenceableCheckStage::probeCheck(
|
||||||
|
|
||||||
void CSMTools::ReferenceableCheckStage::repairCheck (
|
void CSMTools::ReferenceableCheckStage::repairCheck (
|
||||||
int stage, const CSMWorld::RefIdDataContainer< ESM::Repair >& records,
|
int stage, const CSMWorld::RefIdDataContainer< ESM::Repair >& records,
|
||||||
Messages& messages)
|
CSMDoc::Messages& messages)
|
||||||
{
|
{
|
||||||
const CSMWorld::RecordBase& baseRecord = records.getRecord (stage);
|
const CSMWorld::RecordBase& baseRecord = records.getRecord (stage);
|
||||||
|
|
||||||
|
@ -812,7 +812,7 @@ void CSMTools::ReferenceableCheckStage::repairCheck (
|
||||||
|
|
||||||
void CSMTools::ReferenceableCheckStage::staticCheck (
|
void CSMTools::ReferenceableCheckStage::staticCheck (
|
||||||
int stage, const CSMWorld::RefIdDataContainer< ESM::Static >& records,
|
int stage, const CSMWorld::RefIdDataContainer< ESM::Static >& records,
|
||||||
Messages& messages)
|
CSMDoc::Messages& messages)
|
||||||
{
|
{
|
||||||
const CSMWorld::RecordBase& baseRecord = records.getRecord (stage);
|
const CSMWorld::RecordBase& baseRecord = records.getRecord (stage);
|
||||||
|
|
||||||
|
@ -828,7 +828,7 @@ void CSMTools::ReferenceableCheckStage::staticCheck (
|
||||||
|
|
||||||
//final check
|
//final check
|
||||||
|
|
||||||
void CSMTools::ReferenceableCheckStage::finalCheck (Messages& messages)
|
void CSMTools::ReferenceableCheckStage::finalCheck (CSMDoc::Messages& messages)
|
||||||
{
|
{
|
||||||
if (!mPlayerPresent)
|
if (!mPlayerPresent)
|
||||||
messages.push_back (std::make_pair (CSMWorld::UniversalId::Type_Referenceables,
|
messages.push_back (std::make_pair (CSMWorld::UniversalId::Type_Referenceables,
|
||||||
|
@ -839,7 +839,7 @@ void CSMTools::ReferenceableCheckStage::finalCheck (Messages& messages)
|
||||||
//Templates begins here
|
//Templates begins here
|
||||||
|
|
||||||
template<typename Item> void CSMTools::ReferenceableCheckStage::inventoryItemCheck (
|
template<typename Item> void CSMTools::ReferenceableCheckStage::inventoryItemCheck (
|
||||||
const Item& someItem, Messages& messages, const std::string& someID, bool enchantable)
|
const Item& someItem, CSMDoc::Messages& messages, const std::string& someID, bool enchantable)
|
||||||
{
|
{
|
||||||
if (someItem.mName.empty())
|
if (someItem.mName.empty())
|
||||||
messages.push_back (std::make_pair (someID, someItem.mId + " has an empty name"));
|
messages.push_back (std::make_pair (someID, someItem.mId + " has an empty name"));
|
||||||
|
@ -865,7 +865,7 @@ template<typename Item> void CSMTools::ReferenceableCheckStage::inventoryItemChe
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Item> void CSMTools::ReferenceableCheckStage::inventoryItemCheck (
|
template<typename Item> void CSMTools::ReferenceableCheckStage::inventoryItemCheck (
|
||||||
const Item& someItem, Messages& messages, const std::string& someID)
|
const Item& someItem, CSMDoc::Messages& messages, const std::string& someID)
|
||||||
{
|
{
|
||||||
if (someItem.mName.empty())
|
if (someItem.mName.empty())
|
||||||
messages.push_back (std::make_pair (someID, someItem.mId + " has an empty name"));
|
messages.push_back (std::make_pair (someID, someItem.mId + " has an empty name"));
|
||||||
|
@ -888,7 +888,7 @@ template<typename Item> void CSMTools::ReferenceableCheckStage::inventoryItemChe
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Tool> void CSMTools::ReferenceableCheckStage::toolCheck (
|
template<typename Tool> void CSMTools::ReferenceableCheckStage::toolCheck (
|
||||||
const Tool& someTool, Messages& messages, const std::string& someID, bool canBeBroken)
|
const Tool& someTool, CSMDoc::Messages& messages, const std::string& someID, bool canBeBroken)
|
||||||
{
|
{
|
||||||
if (someTool.mData.mQuality <= 0)
|
if (someTool.mData.mQuality <= 0)
|
||||||
messages.push_back (std::make_pair (someID, someTool.mId + " has non-positive quality"));
|
messages.push_back (std::make_pair (someID, someTool.mId + " has non-positive quality"));
|
||||||
|
@ -899,14 +899,14 @@ template<typename Tool> void CSMTools::ReferenceableCheckStage::toolCheck (
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Tool> void CSMTools::ReferenceableCheckStage::toolCheck (
|
template<typename Tool> void CSMTools::ReferenceableCheckStage::toolCheck (
|
||||||
const Tool& someTool, Messages& messages, const std::string& someID)
|
const Tool& someTool, CSMDoc::Messages& messages, const std::string& someID)
|
||||||
{
|
{
|
||||||
if (someTool.mData.mQuality <= 0)
|
if (someTool.mData.mQuality <= 0)
|
||||||
messages.push_back (std::make_pair (someID, someTool.mId + " has non-positive quality"));
|
messages.push_back (std::make_pair (someID, someTool.mId + " has non-positive quality"));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename List> void CSMTools::ReferenceableCheckStage::listCheck (
|
template<typename List> void CSMTools::ReferenceableCheckStage::listCheck (
|
||||||
const List& someList, Messages& messages, const std::string& someID)
|
const List& someList, CSMDoc::Messages& messages, const std::string& someID)
|
||||||
{
|
{
|
||||||
for (unsigned i = 0; i < someList.mList.size(); ++i)
|
for (unsigned i = 0; i < someList.mList.size(); ++i)
|
||||||
{
|
{
|
||||||
|
|
|
@ -17,56 +17,56 @@ namespace CSMTools
|
||||||
const CSMWorld::IdCollection<ESM::Class>& classes,
|
const CSMWorld::IdCollection<ESM::Class>& classes,
|
||||||
const CSMWorld::IdCollection<ESM::Faction>& factions);
|
const CSMWorld::IdCollection<ESM::Faction>& factions);
|
||||||
|
|
||||||
virtual void perform(int stage, Messages& messages);
|
virtual void perform(int stage, CSMDoc::Messages& messages);
|
||||||
virtual int setup();
|
virtual int setup();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
//CONCRETE CHECKS
|
//CONCRETE CHECKS
|
||||||
void bookCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Book >& records, Messages& messages);
|
void bookCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Book >& records, CSMDoc::Messages& messages);
|
||||||
void activatorCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Activator >& records, Messages& messages);
|
void activatorCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Activator >& records, CSMDoc::Messages& messages);
|
||||||
void potionCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Potion>& records, Messages& messages);
|
void potionCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Potion>& records, CSMDoc::Messages& messages);
|
||||||
void apparatusCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Apparatus>& records, Messages& messages);
|
void apparatusCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Apparatus>& records, CSMDoc::Messages& messages);
|
||||||
void armorCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Armor>& records, Messages& messages);
|
void armorCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Armor>& records, CSMDoc::Messages& messages);
|
||||||
void clothingCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Clothing>& records, Messages& messages);
|
void clothingCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Clothing>& records, CSMDoc::Messages& messages);
|
||||||
void containerCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Container>& records, Messages& messages);
|
void containerCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Container>& records, CSMDoc::Messages& messages);
|
||||||
void creatureCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Creature>& records, Messages& messages);
|
void creatureCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Creature>& records, CSMDoc::Messages& messages);
|
||||||
void doorCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Door>& records, Messages& messages);
|
void doorCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Door>& records, CSMDoc::Messages& messages);
|
||||||
void ingredientCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Ingredient>& records, Messages& messages);
|
void ingredientCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Ingredient>& records, CSMDoc::Messages& messages);
|
||||||
void creaturesLevListCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::CreatureLevList>& records, Messages& messages);
|
void creaturesLevListCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::CreatureLevList>& records, CSMDoc::Messages& messages);
|
||||||
void itemLevelledListCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::ItemLevList>& records, Messages& messages);
|
void itemLevelledListCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::ItemLevList>& records, CSMDoc::Messages& messages);
|
||||||
void lightCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Light>& records, Messages& messages);
|
void lightCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Light>& records, CSMDoc::Messages& messages);
|
||||||
void lockpickCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Lockpick>& records, Messages& messages);
|
void lockpickCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Lockpick>& records, CSMDoc::Messages& messages);
|
||||||
void miscCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Miscellaneous>& records, Messages& messages);
|
void miscCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Miscellaneous>& records, CSMDoc::Messages& messages);
|
||||||
void npcCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::NPC>& records, Messages& messages);
|
void npcCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::NPC>& records, CSMDoc::Messages& messages);
|
||||||
void weaponCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Weapon>& records, Messages& messages);
|
void weaponCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Weapon>& records, CSMDoc::Messages& messages);
|
||||||
void probeCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Probe>& records, Messages& messages);
|
void probeCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Probe>& records, CSMDoc::Messages& messages);
|
||||||
void repairCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Repair>& records, Messages& messages);
|
void repairCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Repair>& records, CSMDoc::Messages& messages);
|
||||||
void staticCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Static>& records, Messages& messages);
|
void staticCheck(int stage, const CSMWorld::RefIdDataContainer<ESM::Static>& records, CSMDoc::Messages& messages);
|
||||||
|
|
||||||
//FINAL CHECK
|
//FINAL CHECK
|
||||||
void finalCheck (Messages& messages);
|
void finalCheck (CSMDoc::Messages& messages);
|
||||||
|
|
||||||
//TEMPLATE CHECKS
|
//TEMPLATE CHECKS
|
||||||
template<typename ITEM> void inventoryItemCheck(const ITEM& someItem,
|
template<typename ITEM> void inventoryItemCheck(const ITEM& someItem,
|
||||||
Messages& messages,
|
CSMDoc::Messages& messages,
|
||||||
const std::string& someID,
|
const std::string& someID,
|
||||||
bool enchantable); //for all enchantable items.
|
bool enchantable); //for all enchantable items.
|
||||||
|
|
||||||
template<typename ITEM> void inventoryItemCheck(const ITEM& someItem,
|
template<typename ITEM> void inventoryItemCheck(const ITEM& someItem,
|
||||||
Messages& messages,
|
CSMDoc::Messages& messages,
|
||||||
const std::string& someID); //for non-enchantable items.
|
const std::string& someID); //for non-enchantable items.
|
||||||
|
|
||||||
template<typename TOOL> void toolCheck(const TOOL& someTool,
|
template<typename TOOL> void toolCheck(const TOOL& someTool,
|
||||||
Messages& messages,
|
CSMDoc::Messages& messages,
|
||||||
const std::string& someID,
|
const std::string& someID,
|
||||||
bool canbebroken); //for tools with uses.
|
bool canbebroken); //for tools with uses.
|
||||||
|
|
||||||
template<typename TOOL> void toolCheck(const TOOL& someTool,
|
template<typename TOOL> void toolCheck(const TOOL& someTool,
|
||||||
Messages& messages,
|
CSMDoc::Messages& messages,
|
||||||
const std::string& someID); //for tools without uses.
|
const std::string& someID); //for tools without uses.
|
||||||
|
|
||||||
template<typename LIST> void listCheck(const LIST& someList,
|
template<typename LIST> void listCheck(const LIST& someList,
|
||||||
Messages& messages,
|
CSMDoc::Messages& messages,
|
||||||
const std::string& someID);
|
const std::string& someID);
|
||||||
|
|
||||||
const CSMWorld::RefIdData& mReferencables;
|
const CSMWorld::RefIdData& mReferencables;
|
||||||
|
|
|
@ -17,7 +17,7 @@ int CSMTools::RegionCheckStage::setup()
|
||||||
return mRegions.getSize();
|
return mRegions.getSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSMTools::RegionCheckStage::perform (int stage, Messages& messages)
|
void CSMTools::RegionCheckStage::perform (int stage, CSMDoc::Messages& messages)
|
||||||
{
|
{
|
||||||
const CSMWorld::Record<ESM::Region>& record = mRegions.getRecord (stage);
|
const CSMWorld::Record<ESM::Region>& record = mRegions.getRecord (stage);
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ namespace CSMTools
|
||||||
virtual int setup();
|
virtual int setup();
|
||||||
///< \return number of steps
|
///< \return number of steps
|
||||||
|
|
||||||
virtual void perform (int stage, Messages& messages);
|
virtual void perform (int stage, CSMDoc::Messages& messages);
|
||||||
///< Messages resulting from this tage will be appended to \a messages.
|
///< Messages resulting from this tage will be appended to \a messages.
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ int CSMTools::ReportModel::columnCount (const QModelIndex & parent) const
|
||||||
if (parent.isValid())
|
if (parent.isValid())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return 2;
|
return 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant CSMTools::ReportModel::data (const QModelIndex & index, int role) const
|
QVariant CSMTools::ReportModel::data (const QModelIndex & index, int role) const
|
||||||
|
@ -26,8 +26,11 @@ QVariant CSMTools::ReportModel::data (const QModelIndex & index, int role) const
|
||||||
|
|
||||||
if (index.column()==0)
|
if (index.column()==0)
|
||||||
return static_cast<int> (mRows.at (index.row()).first.getType());
|
return static_cast<int> (mRows.at (index.row()).first.getType());
|
||||||
else
|
|
||||||
return mRows.at (index.row()).second.c_str();
|
if (index.column()==1)
|
||||||
|
return QString::fromUtf8 (mRows.at (index.row()).second.first.c_str());
|
||||||
|
|
||||||
|
return QString::fromUtf8 (mRows.at (index.row()).second.second.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant CSMTools::ReportModel::headerData (int section, Qt::Orientation orientation, int role) const
|
QVariant CSMTools::ReportModel::headerData (int section, Qt::Orientation orientation, int role) const
|
||||||
|
@ -38,7 +41,13 @@ QVariant CSMTools::ReportModel::headerData (int section, Qt::Orientation orienta
|
||||||
if (orientation==Qt::Vertical)
|
if (orientation==Qt::Vertical)
|
||||||
return QVariant();
|
return QVariant();
|
||||||
|
|
||||||
return tr (section==0 ? "Type" : "Description");
|
if (section==0)
|
||||||
|
return "Type";
|
||||||
|
|
||||||
|
if (section==1)
|
||||||
|
return "Description";
|
||||||
|
|
||||||
|
return "Hint";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CSMTools::ReportModel::removeRows (int row, int count, const QModelIndex& parent)
|
bool CSMTools::ReportModel::removeRows (int row, int count, const QModelIndex& parent)
|
||||||
|
@ -51,11 +60,12 @@ bool CSMTools::ReportModel::removeRows (int row, int count, const QModelIndex& p
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSMTools::ReportModel::add (const CSMWorld::UniversalId& id, const std::string& message)
|
void CSMTools::ReportModel::add (const CSMWorld::UniversalId& id, const std::string& message,
|
||||||
|
const std::string& hint)
|
||||||
{
|
{
|
||||||
beginInsertRows (QModelIndex(), mRows.size(), mRows.size());
|
beginInsertRows (QModelIndex(), mRows.size(), mRows.size());
|
||||||
|
|
||||||
mRows.push_back (std::make_pair (id, message));
|
mRows.push_back (std::make_pair (id, std::make_pair (message, hint)));
|
||||||
|
|
||||||
endInsertRows();
|
endInsertRows();
|
||||||
}
|
}
|
||||||
|
@ -64,3 +74,8 @@ const CSMWorld::UniversalId& CSMTools::ReportModel::getUniversalId (int row) con
|
||||||
{
|
{
|
||||||
return mRows.at (row).first;
|
return mRows.at (row).first;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string CSMTools::ReportModel::getHint (int row) const
|
||||||
|
{
|
||||||
|
return mRows.at (row).second.second;
|
||||||
|
}
|
|
@ -14,7 +14,7 @@ namespace CSMTools
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
std::vector<std::pair<CSMWorld::UniversalId, std::string> > mRows;
|
std::vector<std::pair<CSMWorld::UniversalId, std::pair<std::string, std::string> > > mRows;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -28,9 +28,12 @@ namespace CSMTools
|
||||||
|
|
||||||
virtual bool removeRows (int row, int count, const QModelIndex& parent = QModelIndex());
|
virtual bool removeRows (int row, int count, const QModelIndex& parent = QModelIndex());
|
||||||
|
|
||||||
void add (const CSMWorld::UniversalId& id, const std::string& message);
|
void add (const CSMWorld::UniversalId& id, const std::string& message,
|
||||||
|
const std::string& hint = "");
|
||||||
|
|
||||||
const CSMWorld::UniversalId& getUniversalId (int row) const;
|
const CSMWorld::UniversalId& getUniversalId (int row) const;
|
||||||
|
|
||||||
|
std::string getHint (int row) const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,11 @@ void CSMTools::ScriptCheckStage::report (const std::string& message, const Compi
|
||||||
<< ", line " << loc.mLine << ", column " << loc.mColumn
|
<< ", line " << loc.mLine << ", column " << loc.mColumn
|
||||||
<< " (" << loc.mLiteral << "): " << message;
|
<< " (" << loc.mLiteral << "): " << message;
|
||||||
|
|
||||||
mMessages->push_back (std::make_pair (id, stream.str()));
|
std::ostringstream hintStream;
|
||||||
|
|
||||||
|
hintStream << "l:" << loc.mLine << " " << loc.mColumn;
|
||||||
|
|
||||||
|
mMessages->add (id, stream.str(), hintStream.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSMTools::ScriptCheckStage::report (const std::string& message, Type type)
|
void CSMTools::ScriptCheckStage::report (const std::string& message, Type type)
|
||||||
|
@ -58,7 +62,7 @@ int CSMTools::ScriptCheckStage::setup()
|
||||||
return mDocument.getData().getScripts().getSize();
|
return mDocument.getData().getScripts().getSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSMTools::ScriptCheckStage::perform (int stage, Messages& messages)
|
void CSMTools::ScriptCheckStage::perform (int stage, CSMDoc::Messages& messages)
|
||||||
{
|
{
|
||||||
mId = mDocument.getData().getScripts().getId (stage);
|
mId = mDocument.getData().getScripts().getId (stage);
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ namespace CSMTools
|
||||||
CSMWorld::ScriptContext mContext;
|
CSMWorld::ScriptContext mContext;
|
||||||
std::string mId;
|
std::string mId;
|
||||||
std::string mFile;
|
std::string mFile;
|
||||||
Messages *mMessages;
|
CSMDoc::Messages *mMessages;
|
||||||
|
|
||||||
virtual void report (const std::string& message, const Compiler::TokenLoc& loc, Type type);
|
virtual void report (const std::string& message, const Compiler::TokenLoc& loc, Type type);
|
||||||
///< Report error to the user.
|
///< Report error to the user.
|
||||||
|
@ -38,7 +38,7 @@ namespace CSMTools
|
||||||
virtual int setup();
|
virtual int setup();
|
||||||
///< \return number of steps
|
///< \return number of steps
|
||||||
|
|
||||||
virtual void perform (int stage, Messages& messages);
|
virtual void perform (int stage, CSMDoc::Messages& messages);
|
||||||
///< Messages resulting from this tage will be appended to \a messages.
|
///< Messages resulting from this tage will be appended to \a messages.
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ int CSMTools::SkillCheckStage::setup()
|
||||||
return mSkills.getSize();
|
return mSkills.getSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSMTools::SkillCheckStage::perform (int stage, Messages& messages)
|
void CSMTools::SkillCheckStage::perform (int stage, CSMDoc::Messages& messages)
|
||||||
{
|
{
|
||||||
const CSMWorld::Record<ESM::Skill>& record = mSkills.getRecord (stage);
|
const CSMWorld::Record<ESM::Skill>& record = mSkills.getRecord (stage);
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ namespace CSMTools
|
||||||
virtual int setup();
|
virtual int setup();
|
||||||
///< \return number of steps
|
///< \return number of steps
|
||||||
|
|
||||||
virtual void perform (int stage, Messages& messages);
|
virtual void perform (int stage, CSMDoc::Messages& messages);
|
||||||
///< Messages resulting from this tage will be appended to \a messages.
|
///< Messages resulting from this tage will be appended to \a messages.
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ int CSMTools::SoundCheckStage::setup()
|
||||||
return mSounds.getSize();
|
return mSounds.getSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSMTools::SoundCheckStage::perform (int stage, Messages& messages)
|
void CSMTools::SoundCheckStage::perform (int stage, CSMDoc::Messages& messages)
|
||||||
{
|
{
|
||||||
const CSMWorld::Record<ESM::Sound>& record = mSounds.getRecord (stage);
|
const CSMWorld::Record<ESM::Sound>& record = mSounds.getRecord (stage);
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ namespace CSMTools
|
||||||
virtual int setup();
|
virtual int setup();
|
||||||
///< \return number of steps
|
///< \return number of steps
|
||||||
|
|
||||||
virtual void perform (int stage, Messages& messages);
|
virtual void perform (int stage, CSMDoc::Messages& messages);
|
||||||
///< Messages resulting from this tage will be appended to \a messages.
|
///< Messages resulting from this tage will be appended to \a messages.
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ int CSMTools::SpellCheckStage::setup()
|
||||||
return mSpells.getSize();
|
return mSpells.getSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSMTools::SpellCheckStage::perform (int stage, Messages& messages)
|
void CSMTools::SpellCheckStage::perform (int stage, CSMDoc::Messages& messages)
|
||||||
{
|
{
|
||||||
const CSMWorld::Record<ESM::Spell>& record = mSpells.getRecord (stage);
|
const CSMWorld::Record<ESM::Spell>& record = mSpells.getRecord (stage);
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ namespace CSMTools
|
||||||
virtual int setup();
|
virtual int setup();
|
||||||
///< \return number of steps
|
///< \return number of steps
|
||||||
|
|
||||||
virtual void perform (int stage, Messages& messages);
|
virtual void perform (int stage, CSMDoc::Messages& messages);
|
||||||
///< Messages resulting from this tage will be appended to \a messages.
|
///< Messages resulting from this tage will be appended to \a messages.
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,8 +48,8 @@ CSMDoc::Operation *CSMTools::Tools::getVerifier()
|
||||||
connect (mVerifier, SIGNAL (progress (int, int, int)), this, SIGNAL (progress (int, int, int)));
|
connect (mVerifier, SIGNAL (progress (int, int, int)), this, SIGNAL (progress (int, int, int)));
|
||||||
connect (mVerifier, SIGNAL (done (int, bool)), this, SIGNAL (done (int, bool)));
|
connect (mVerifier, SIGNAL (done (int, bool)), this, SIGNAL (done (int, bool)));
|
||||||
connect (mVerifier,
|
connect (mVerifier,
|
||||||
SIGNAL (reportMessage (const CSMWorld::UniversalId&, const std::string&, int)),
|
SIGNAL (reportMessage (const CSMWorld::UniversalId&, const std::string&, const std::string&, int)),
|
||||||
this, SLOT (verifierMessage (const CSMWorld::UniversalId&, const std::string&, int)));
|
this, SLOT (verifierMessage (const CSMWorld::UniversalId&, const std::string&, const std::string&, int)));
|
||||||
|
|
||||||
std::vector<std::string> mandatoryIds; // I want C++11, damn it!
|
std::vector<std::string> mandatoryIds; // I want C++11, damn it!
|
||||||
mandatoryIds.push_back ("Day");
|
mandatoryIds.push_back ("Day");
|
||||||
|
@ -155,11 +155,11 @@ CSMTools::ReportModel *CSMTools::Tools::getReport (const CSMWorld::UniversalId&
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSMTools::Tools::verifierMessage (const CSMWorld::UniversalId& id, const std::string& message,
|
void CSMTools::Tools::verifierMessage (const CSMWorld::UniversalId& id, const std::string& message,
|
||||||
int type)
|
const std::string& hint, int type)
|
||||||
{
|
{
|
||||||
std::map<int, int>::iterator iter = mActiveReports.find (type);
|
std::map<int, int>::iterator iter = mActiveReports.find (type);
|
||||||
|
|
||||||
if (iter!=mActiveReports.end())
|
if (iter!=mActiveReports.end())
|
||||||
mReports[iter->second]->add (id, message);
|
mReports[iter->second]->add (id, message, hint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -64,7 +64,7 @@ namespace CSMTools
|
||||||
private slots:
|
private slots:
|
||||||
|
|
||||||
void verifierMessage (const CSMWorld::UniversalId& id, const std::string& message,
|
void verifierMessage (const CSMWorld::UniversalId& id, const std::string& message,
|
||||||
int type);
|
const std::string& hint, int type);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
|
|
|
@ -272,7 +272,7 @@ namespace CSMWorld
|
||||||
{
|
{
|
||||||
ESXRecordT record2 = record.get();
|
ESXRecordT record2 = record.get();
|
||||||
|
|
||||||
record2.mData.mUseValue[mIndex] = data.toInt();
|
record2.mData.mUseValue[mIndex] = data.toFloat();
|
||||||
|
|
||||||
record.setModified (record2);
|
record.setModified (record2);
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,7 +60,7 @@ int CSMWorld::Data::count (RecordBase::State state, const CollectionBase& collec
|
||||||
|
|
||||||
CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourcesManager)
|
CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourcesManager)
|
||||||
: mEncoder (encoding), mPathgrids (mCells), mRefs (mCells),
|
: mEncoder (encoding), mPathgrids (mCells), mRefs (mCells),
|
||||||
mResourcesManager (resourcesManager), mReader (0), mDialogue (0)
|
mResourcesManager (resourcesManager), mReader (0), mDialogue (0), mReaderIndex(0)
|
||||||
{
|
{
|
||||||
mGlobals.addColumn (new StringIdColumn<ESM::Global>);
|
mGlobals.addColumn (new StringIdColumn<ESM::Global>);
|
||||||
mGlobals.addColumn (new RecordStateColumn<ESM::Global>);
|
mGlobals.addColumn (new RecordStateColumn<ESM::Global>);
|
||||||
|
@ -659,6 +659,7 @@ int CSMWorld::Data::startLoading (const boost::filesystem::path& path, bool base
|
||||||
|
|
||||||
mReader = new ESM::ESMReader;
|
mReader = new ESM::ESMReader;
|
||||||
mReader->setEncoder (&mEncoder);
|
mReader->setEncoder (&mEncoder);
|
||||||
|
mReader->setIndex(mReaderIndex++);
|
||||||
mReader->open (path.string());
|
mReader->open (path.string());
|
||||||
|
|
||||||
mBase = base;
|
mBase = base;
|
||||||
|
@ -670,16 +671,24 @@ int CSMWorld::Data::startLoading (const boost::filesystem::path& path, bool base
|
||||||
return mReader->getRecordCount();
|
return mReader->getRecordCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CSMWorld::Data::continueLoading (CSMDoc::Stage::Messages& messages)
|
bool CSMWorld::Data::continueLoading (CSMDoc::Messages& messages)
|
||||||
{
|
{
|
||||||
if (!mReader)
|
if (!mReader)
|
||||||
throw std::logic_error ("can't continue loading, because no load has been started");
|
throw std::logic_error ("can't continue loading, because no load has been started");
|
||||||
|
|
||||||
if (!mReader->hasMoreRecs())
|
if (!mReader->hasMoreRecs())
|
||||||
{
|
{
|
||||||
// Don't delete the Reader yet. Some record types store a reference to the Reader to handle on-demand loading
|
if (mBase)
|
||||||
|
{
|
||||||
|
// Don't delete the Reader yet. Some record types store a reference to the Reader to handle on-demand loading.
|
||||||
|
// We don't store non-base reader, because everything going into modified will be
|
||||||
|
// fully loaded during the initial loading process.
|
||||||
boost::shared_ptr<ESM::ESMReader> ptr(mReader);
|
boost::shared_ptr<ESM::ESMReader> ptr(mReader);
|
||||||
mReaders.push_back(ptr);
|
mReaders.push_back(ptr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
delete mReader;
|
||||||
|
|
||||||
mReader = 0;
|
mReader = 0;
|
||||||
|
|
||||||
mDialogue = 0;
|
mDialogue = 0;
|
||||||
|
@ -712,7 +721,18 @@ bool CSMWorld::Data::continueLoading (CSMDoc::Stage::Messages& messages)
|
||||||
case ESM::REC_PGRD: mPathgrids.load (*mReader, mBase); break;
|
case ESM::REC_PGRD: mPathgrids.load (*mReader, mBase); break;
|
||||||
|
|
||||||
case ESM::REC_LTEX: mLandTextures.load (*mReader, mBase); break;
|
case ESM::REC_LTEX: mLandTextures.load (*mReader, mBase); break;
|
||||||
case ESM::REC_LAND: mLand.load(*mReader, mBase); break;
|
|
||||||
|
case ESM::REC_LAND:
|
||||||
|
{
|
||||||
|
int index = mLand.load(*mReader, mBase);
|
||||||
|
|
||||||
|
if (index!=-1 && !mBase)
|
||||||
|
mLand.getRecord (index).mModified.mLand->loadData (
|
||||||
|
ESM::Land::DATA_VHGT | ESM::Land::DATA_VNML | ESM::Land::DATA_VCLR |
|
||||||
|
ESM::Land::DATA_VTEX);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case ESM::REC_CELL:
|
case ESM::REC_CELL:
|
||||||
{
|
{
|
||||||
|
@ -774,8 +794,8 @@ bool CSMWorld::Data::continueLoading (CSMDoc::Stage::Messages& messages)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
messages.push_back (std::make_pair (UniversalId::Type_None,
|
messages.add (UniversalId::Type_None,
|
||||||
"Trying to delete dialogue record " + id + " which does not exist"));
|
"Trying to delete dialogue record " + id + " which does not exist");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -791,8 +811,8 @@ bool CSMWorld::Data::continueLoading (CSMDoc::Stage::Messages& messages)
|
||||||
{
|
{
|
||||||
if (!mDialogue)
|
if (!mDialogue)
|
||||||
{
|
{
|
||||||
messages.push_back (std::make_pair (UniversalId::Type_None,
|
messages.add (UniversalId::Type_None,
|
||||||
"Found info record not following a dialogue record"));
|
"Found info record not following a dialogue record");
|
||||||
|
|
||||||
mReader->skipRecord();
|
mReader->skipRecord();
|
||||||
break;
|
break;
|
||||||
|
@ -835,8 +855,7 @@ bool CSMWorld::Data::continueLoading (CSMDoc::Stage::Messages& messages)
|
||||||
|
|
||||||
if (unhandledRecord)
|
if (unhandledRecord)
|
||||||
{
|
{
|
||||||
messages.push_back (std::make_pair (UniversalId::Type_None,
|
messages.add (UniversalId::Type_None, "Unsupported record type: " + n.toString());
|
||||||
"Unsupported record type: " + n.toString()));
|
|
||||||
|
|
||||||
mReader->skipRecord();
|
mReader->skipRecord();
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,6 +98,7 @@ namespace CSMWorld
|
||||||
bool mBase;
|
bool mBase;
|
||||||
bool mProject;
|
bool mProject;
|
||||||
std::map<std::string, std::map<ESM::RefNum, std::string> > mRefLoadCache;
|
std::map<std::string, std::map<ESM::RefNum, std::string> > mRefLoadCache;
|
||||||
|
int mReaderIndex;
|
||||||
|
|
||||||
std::vector<boost::shared_ptr<ESM::ESMReader> > mReaders;
|
std::vector<boost::shared_ptr<ESM::ESMReader> > mReaders;
|
||||||
|
|
||||||
|
@ -243,7 +244,7 @@ namespace CSMWorld
|
||||||
///
|
///
|
||||||
///< \return estimated number of records
|
///< \return estimated number of records
|
||||||
|
|
||||||
bool continueLoading (CSMDoc::Stage::Messages& messages);
|
bool continueLoading (CSMDoc::Messages& messages);
|
||||||
///< \return Finished?
|
///< \return Finished?
|
||||||
|
|
||||||
bool hasId (const std::string& id) const;
|
bool hasId (const std::string& id) const;
|
||||||
|
|
|
@ -15,12 +15,15 @@ namespace CSMWorld
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void load (ESM::ESMReader& reader, bool base);
|
/// \return Index of loaded record (-1 if no record was loaded)
|
||||||
|
int load (ESM::ESMReader& reader, bool base);
|
||||||
|
|
||||||
/// \param index Index at which the record can be found.
|
/// \param index Index at which the record can be found.
|
||||||
/// Special values: -2 index unknown, -1 record does not exist yet and therefore
|
/// Special values: -2 index unknown, -1 record does not exist yet and therefore
|
||||||
/// does not have an index
|
/// does not have an index
|
||||||
void load (const ESXRecordT& record, bool base, int index = -2);
|
///
|
||||||
|
/// \return index
|
||||||
|
int load (const ESXRecordT& record, bool base, int index = -2);
|
||||||
|
|
||||||
bool tryDelete (const std::string& id);
|
bool tryDelete (const std::string& id);
|
||||||
///< Try deleting \a id. If the id does not exist or can't be deleted the call is ignored.
|
///< Try deleting \a id. If the id does not exist or can't be deleted the call is ignored.
|
||||||
|
@ -36,7 +39,7 @@ namespace CSMWorld
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename ESXRecordT, typename IdAccessorT>
|
template<typename ESXRecordT, typename IdAccessorT>
|
||||||
void IdCollection<ESXRecordT, IdAccessorT>::load (ESM::ESMReader& reader, bool base)
|
int IdCollection<ESXRecordT, IdAccessorT>::load (ESM::ESMReader& reader, bool base)
|
||||||
{
|
{
|
||||||
std::string id = reader.getHNOString ("NAME");
|
std::string id = reader.getHNOString ("NAME");
|
||||||
|
|
||||||
|
@ -64,6 +67,8 @@ namespace CSMWorld
|
||||||
record.mState = RecordBase::State_Deleted;
|
record.mState = RecordBase::State_Deleted;
|
||||||
this->setRecord (index, record);
|
this->setRecord (index, record);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -88,12 +93,12 @@ namespace CSMWorld
|
||||||
index = newIndex;
|
index = newIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
load (record, base, index);
|
return load (record, base, index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename ESXRecordT, typename IdAccessorT>
|
template<typename ESXRecordT, typename IdAccessorT>
|
||||||
void IdCollection<ESXRecordT, IdAccessorT>::load (const ESXRecordT& record, bool base,
|
int IdCollection<ESXRecordT, IdAccessorT>::load (const ESXRecordT& record, bool base,
|
||||||
int index)
|
int index)
|
||||||
{
|
{
|
||||||
if (index==-2)
|
if (index==-2)
|
||||||
|
@ -106,6 +111,7 @@ namespace CSMWorld
|
||||||
record2.mState = base ? RecordBase::State_BaseOnly : RecordBase::State_ModifiedOnly;
|
record2.mState = base ? RecordBase::State_BaseOnly : RecordBase::State_ModifiedOnly;
|
||||||
(base ? record2.mBase : record2.mModified) = record;
|
(base ? record2.mBase : record2.mModified) = record;
|
||||||
|
|
||||||
|
index = this->getSize();
|
||||||
this->appendRecord (record2);
|
this->appendRecord (record2);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -120,6 +126,8 @@ namespace CSMWorld
|
||||||
|
|
||||||
this->setRecord (index, record2);
|
this->setRecord (index, record2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename ESXRecordT, typename IdAccessorT>
|
template<typename ESXRecordT, typename IdAccessorT>
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
#include "record.hpp"
|
#include "record.hpp"
|
||||||
|
|
||||||
void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool base,
|
void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool base,
|
||||||
std::map<ESM::RefNum, std::string>& cache, CSMDoc::Stage::Messages& messages)
|
std::map<ESM::RefNum, std::string>& cache, CSMDoc::Messages& messages)
|
||||||
{
|
{
|
||||||
Record<Cell> cell = mCells.getRecord (cellIndex);
|
Record<Cell> cell = mCells.getRecord (cellIndex);
|
||||||
|
|
||||||
|
@ -36,8 +36,7 @@ void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool
|
||||||
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Cell,
|
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Cell,
|
||||||
mCells.getId (cellIndex));
|
mCells.getId (cellIndex));
|
||||||
|
|
||||||
messages.push_back (std::make_pair (id,
|
messages.add (id, "Attempt to delete a non-existing reference");
|
||||||
"Attempt to delete a non-existing reference"));
|
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ namespace CSMWorld
|
||||||
|
|
||||||
void load (ESM::ESMReader& reader, int cellIndex, bool base,
|
void load (ESM::ESMReader& reader, int cellIndex, bool base,
|
||||||
std::map<ESM::RefNum, std::string>& cache,
|
std::map<ESM::RefNum, std::string>& cache,
|
||||||
CSMDoc::Stage::Messages& messages);
|
CSMDoc::Messages& messages);
|
||||||
///< Load a sequence of references.
|
///< Load a sequence of references.
|
||||||
|
|
||||||
std::string getNewId();
|
std::string getNewId();
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
#include <OgreResourceGroupManager.h>
|
#include <OgreResourceGroupManager.h>
|
||||||
|
|
||||||
|
@ -55,7 +56,9 @@ CSMWorld::Resources::Resources (const std::string& baseDirectory, UniversalId::T
|
||||||
|
|
||||||
std::string file = iter->substr (baseSize+1);
|
std::string file = iter->substr (baseSize+1);
|
||||||
mFiles.push_back (file);
|
mFiles.push_back (file);
|
||||||
mIndex.insert (std::make_pair (file, static_cast<int> (mFiles.size())-1));
|
std::replace (file.begin(), file.end(), '\\', '/');
|
||||||
|
mIndex.insert (std::make_pair (
|
||||||
|
Misc::StringUtils::lowerCase (file), static_cast<int> (mFiles.size())-1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -89,6 +92,8 @@ int CSMWorld::Resources::searchId (const std::string& id) const
|
||||||
{
|
{
|
||||||
std::string id2 = Misc::StringUtils::lowerCase (id);
|
std::string id2 = Misc::StringUtils::lowerCase (id);
|
||||||
|
|
||||||
|
std::replace (id2.begin(), id2.end(), '\\', '/');
|
||||||
|
|
||||||
std::map<std::string, int>::const_iterator iter = mIndex.find (id2);
|
std::map<std::string, int>::const_iterator iter = mIndex.find (id2);
|
||||||
|
|
||||||
if (iter==mIndex.end())
|
if (iter==mIndex.end())
|
||||||
|
|
|
@ -328,7 +328,7 @@ std::string CSMWorld::UniversalId::getIcon() const
|
||||||
|
|
||||||
for (int i=0; typeData[i].mName; ++i)
|
for (int i=0; typeData[i].mName; ++i)
|
||||||
if (typeData[i].mType==mType)
|
if (typeData[i].mType==mType)
|
||||||
return typeData[i].mIcon ? typeData[i].mIcon : "";
|
return typeData[i].mIcon ? typeData[i].mIcon : ":placeholder";
|
||||||
|
|
||||||
throw std::logic_error ("failed to retrieve UniversalId type icon");
|
throw std::logic_error ("failed to retrieve UniversalId type icon");
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
#include "../../model/world/idtable.hpp"
|
#include "../../model/world/idtable.hpp"
|
||||||
|
|
||||||
#include "../world/subviews.hpp"
|
#include "../world/subviews.hpp"
|
||||||
#include "../world/physicsmanager.hpp"
|
|
||||||
|
|
||||||
#include "../tools/subviews.hpp"
|
#include "../tools/subviews.hpp"
|
||||||
|
|
||||||
|
@ -407,8 +406,6 @@ CSVDoc::View::View (ViewManager& viewManager, CSMDoc::Document *document, int to
|
||||||
mSubViewFactory.add (CSMWorld::UniversalId::Type_RunLog, new SubViewFactory<RunLogSubView>);
|
mSubViewFactory.add (CSMWorld::UniversalId::Type_RunLog, new SubViewFactory<RunLogSubView>);
|
||||||
|
|
||||||
connect (mOperations, SIGNAL (abortOperation (int)), this, SLOT (abortOperation (int)));
|
connect (mOperations, SIGNAL (abortOperation (int)), this, SLOT (abortOperation (int)));
|
||||||
|
|
||||||
CSVWorld::PhysicsManager::instance()->setupPhysics(document);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CSVDoc::View::~View()
|
CSVDoc::View::~View()
|
||||||
|
@ -464,8 +461,7 @@ void CSVDoc::View::addSubView (const CSMWorld::UniversalId& id, const std::strin
|
||||||
{
|
{
|
||||||
CSMSettings::UserSettings &userSettings = CSMSettings::UserSettings::instance();
|
CSMSettings::UserSettings &userSettings = CSMSettings::UserSettings::instance();
|
||||||
|
|
||||||
const std::vector<CSMWorld::UniversalId::Type> referenceables(CSMWorld::UniversalId::listReferenceableTypes());
|
bool isReferenceable = id.getClass() == CSMWorld::UniversalId::Class_RefRecord;
|
||||||
bool isReferenceable = std::find(referenceables.begin(), referenceables.end(), id.getType()) != referenceables.end();
|
|
||||||
|
|
||||||
// User setting to reuse sub views (on a per top level view basis)
|
// User setting to reuse sub views (on a per top level view basis)
|
||||||
bool reuse =
|
bool reuse =
|
||||||
|
@ -474,10 +470,14 @@ void CSVDoc::View::addSubView (const CSMWorld::UniversalId& id, const std::strin
|
||||||
{
|
{
|
||||||
foreach(SubView *sb, mSubViews)
|
foreach(SubView *sb, mSubViews)
|
||||||
{
|
{
|
||||||
if((isReferenceable && (CSMWorld::UniversalId(CSMWorld::UniversalId::Type_Referenceable, id.getId()) == CSMWorld::UniversalId(CSMWorld::UniversalId::Type_Referenceable, sb->getUniversalId().getId())))
|
bool isSubViewReferenceable =
|
||||||
|| (!isReferenceable && (id == sb->getUniversalId())))
|
sb->getUniversalId().getType() == CSMWorld::UniversalId::Type_Referenceable;
|
||||||
|
|
||||||
|
if((isReferenceable && isSubViewReferenceable && id.getId() == sb->getUniversalId().getId())
|
||||||
|
||
|
||||||
|
(!isReferenceable && id == sb->getUniversalId()))
|
||||||
{
|
{
|
||||||
sb->setFocus(Qt::OtherFocusReason); // FIXME: focus not quite working
|
sb->setFocus();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -497,7 +497,7 @@ void CSVDoc::View::addSubView (const CSMWorld::UniversalId& id, const std::strin
|
||||||
}
|
}
|
||||||
|
|
||||||
SubView *view = NULL;
|
SubView *view = NULL;
|
||||||
if(std::find(referenceables.begin(), referenceables.end(), id.getType()) != referenceables.end())
|
if(isReferenceable)
|
||||||
{
|
{
|
||||||
view = mSubViewFactory.makeSubView (CSMWorld::UniversalId(CSMWorld::UniversalId::Type_Referenceable, id.getId()), *mDocument);
|
view = mSubViewFactory.makeSubView (CSMWorld::UniversalId(CSMWorld::UniversalId::Type_Referenceable, id.getId()), *mDocument);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
#include "../world/vartypedelegate.hpp"
|
#include "../world/vartypedelegate.hpp"
|
||||||
#include "../world/recordstatusdelegate.hpp"
|
#include "../world/recordstatusdelegate.hpp"
|
||||||
#include "../world/idtypedelegate.hpp"
|
#include "../world/idtypedelegate.hpp"
|
||||||
#include "../world/physicsmanager.hpp"
|
|
||||||
|
|
||||||
#include "../../model/settings/usersettings.hpp"
|
#include "../../model/settings/usersettings.hpp"
|
||||||
|
|
||||||
|
@ -219,7 +218,6 @@ void CSVDoc::ViewManager::removeDocAndView (CSMDoc::Document *document)
|
||||||
mDocumentManager.removeDocument(document);
|
mDocumentManager.removeDocument(document);
|
||||||
(*iter)->deleteLater();
|
(*iter)->deleteLater();
|
||||||
mViews.erase (iter);
|
mViews.erase (iter);
|
||||||
CSVWorld::PhysicsManager::instance()->removeDocument(document);
|
|
||||||
|
|
||||||
updateIndices();
|
updateIndices();
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -60,7 +60,7 @@ bool CSVRender::Cell::addObjects (int start, int end)
|
||||||
}
|
}
|
||||||
|
|
||||||
CSVRender::Cell::Cell (CSMWorld::Data& data, Ogre::SceneManager *sceneManager,
|
CSVRender::Cell::Cell (CSMWorld::Data& data, Ogre::SceneManager *sceneManager,
|
||||||
const std::string& id, CSVWorld::PhysicsSystem *physics, const Ogre::Vector3& origin)
|
const std::string& id, boost::shared_ptr<CSVWorld::PhysicsSystem> physics, const Ogre::Vector3& origin)
|
||||||
: mData (data), mId (Misc::StringUtils::lowerCase (id)), mSceneMgr(sceneManager), mPhysics(physics)
|
: mData (data), mId (Misc::StringUtils::lowerCase (id)), mSceneMgr(sceneManager), mPhysics(physics)
|
||||||
{
|
{
|
||||||
mCellNode = sceneManager->getRootSceneNode()->createChildSceneNode();
|
mCellNode = sceneManager->getRootSceneNode()->createChildSceneNode();
|
||||||
|
|
|
@ -3,6 +3,9 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
#include <OgreVector3.h>
|
#include <OgreVector3.h>
|
||||||
|
|
||||||
|
@ -37,7 +40,7 @@ namespace CSVRender
|
||||||
Ogre::SceneNode *mCellNode;
|
Ogre::SceneNode *mCellNode;
|
||||||
std::map<std::string, Object *> mObjects;
|
std::map<std::string, Object *> mObjects;
|
||||||
std::auto_ptr<Terrain::TerrainGrid> mTerrain;
|
std::auto_ptr<Terrain::TerrainGrid> mTerrain;
|
||||||
CSVWorld::PhysicsSystem *mPhysics;
|
boost::shared_ptr<CSVWorld::PhysicsSystem> mPhysics;
|
||||||
Ogre::SceneManager *mSceneMgr;
|
Ogre::SceneManager *mSceneMgr;
|
||||||
int mX;
|
int mX;
|
||||||
int mY;
|
int mY;
|
||||||
|
@ -55,7 +58,7 @@ namespace CSVRender
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Cell (CSMWorld::Data& data, Ogre::SceneManager *sceneManager, const std::string& id,
|
Cell (CSMWorld::Data& data, Ogre::SceneManager *sceneManager, const std::string& id,
|
||||||
CSVWorld::PhysicsSystem *physics, const Ogre::Vector3& origin = Ogre::Vector3 (0, 0, 0));
|
boost::shared_ptr<CSVWorld::PhysicsSystem> physics, const Ogre::Vector3& origin = Ogre::Vector3 (0, 0, 0));
|
||||||
|
|
||||||
~Cell();
|
~Cell();
|
||||||
|
|
||||||
|
|
19
apps/opencs/view/render/editmode.cpp
Normal file
19
apps/opencs/view/render/editmode.cpp
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
|
||||||
|
#include "editmode.hpp"
|
||||||
|
|
||||||
|
#include "worldspacewidget.hpp"
|
||||||
|
|
||||||
|
CSVRender::EditMode::EditMode (WorldspaceWidget *worldspaceWidget, const QIcon& icon,
|
||||||
|
unsigned int mask, const QString& tooltip, QWidget *parent)
|
||||||
|
: ModeButton (icon, tooltip, parent), mWorldspaceWidget (worldspaceWidget), mMask (mask)
|
||||||
|
{}
|
||||||
|
|
||||||
|
unsigned int CSVRender::EditMode::getInteractionMask() const
|
||||||
|
{
|
||||||
|
return mMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::EditMode::activate (CSVWidget::SceneToolbar *toolbar)
|
||||||
|
{
|
||||||
|
mWorldspaceWidget->setInteractionMask (mMask);
|
||||||
|
}
|
28
apps/opencs/view/render/editmode.hpp
Normal file
28
apps/opencs/view/render/editmode.hpp
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
#ifndef CSV_RENDER_EDITMODE_H
|
||||||
|
#define CSV_RENDER_EDITMODE_H
|
||||||
|
|
||||||
|
#include "../widget/modebutton.hpp"
|
||||||
|
|
||||||
|
namespace CSVRender
|
||||||
|
{
|
||||||
|
class WorldspaceWidget;
|
||||||
|
|
||||||
|
class EditMode : public CSVWidget::ModeButton
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
WorldspaceWidget *mWorldspaceWidget;
|
||||||
|
unsigned int mMask;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
EditMode (WorldspaceWidget *worldspaceWidget, const QIcon& icon, unsigned int mask,
|
||||||
|
const QString& tooltip = "", QWidget *parent = 0);
|
||||||
|
|
||||||
|
unsigned int getInteractionMask() const;
|
||||||
|
|
||||||
|
virtual void activate (CSVWidget::SceneToolbar *toolbar);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -8,10 +8,10 @@ namespace CSVRender
|
||||||
{
|
{
|
||||||
// elements that are part of the actual scene
|
// elements that are part of the actual scene
|
||||||
Element_Reference = 0x1,
|
Element_Reference = 0x1,
|
||||||
Element_Terrain = 0x2,
|
Element_Pathgrid = 0x2,
|
||||||
Element_Water = 0x4,
|
Element_Water = 0x4,
|
||||||
Element_Pathgrid = 0x8,
|
Element_Fog = 0x8,
|
||||||
Element_Fog = 0x10,
|
Element_Terrain = 0x10,
|
||||||
|
|
||||||
// control elements
|
// control elements
|
||||||
Element_CellMarker = 0x10000,
|
Element_CellMarker = 0x10000,
|
||||||
|
|
|
@ -56,7 +56,7 @@ namespace CSVRender
|
||||||
//
|
//
|
||||||
|
|
||||||
MouseState::MouseState(WorldspaceWidget *parent)
|
MouseState::MouseState(WorldspaceWidget *parent)
|
||||||
: mParent(parent), mPhysics(parent->getPhysics()), mSceneManager(parent->getSceneManager())
|
: mParent(parent), mPhysics(parent->mDocument.getPhysics()), mSceneManager(parent->getSceneManager())
|
||||||
, mCurrentObj(""), mMouseState(Mouse_Default), mOldPos(0,0), mMouseEventTimer(0), mPlane(0)
|
, mCurrentObj(""), mMouseState(Mouse_Default), mOldPos(0,0), mMouseEventTimer(0), mPlane(0)
|
||||||
, mGrabbedSceneNode(""), mOrigObjPos(Ogre::Vector3()), mOrigMousePos(Ogre::Vector3())
|
, mGrabbedSceneNode(""), mOrigObjPos(Ogre::Vector3()), mOrigMousePos(Ogre::Vector3())
|
||||||
, mCurrentMousePos(Ogre::Vector3()), mOffset(0.0f)
|
, mCurrentMousePos(Ogre::Vector3()), mOffset(0.0f)
|
||||||
|
@ -255,7 +255,7 @@ namespace CSVRender
|
||||||
std::pair<std::string, Ogre::Vector3> result = terrainUnderCursor(event->x(), event->y());
|
std::pair<std::string, Ogre::Vector3> result = terrainUnderCursor(event->x(), event->y());
|
||||||
if(result.first != "")
|
if(result.first != "")
|
||||||
{
|
{
|
||||||
// FIXME: terrain editing
|
// FIXME: terrain editing goes here
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -267,6 +267,8 @@ namespace CSVRender
|
||||||
void MouseState::mouseDoubleClickEvent (QMouseEvent *event)
|
void MouseState::mouseDoubleClickEvent (QMouseEvent *event)
|
||||||
{
|
{
|
||||||
event->ignore();
|
event->ignore();
|
||||||
|
//mPhysics->toggleDebugRendering(mSceneManager);
|
||||||
|
//mParent->flagAsModified();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MouseState::wheelEvent (QWheelEvent *event)
|
bool MouseState::wheelEvent (QWheelEvent *event)
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define OPENCS_VIEW_MOUSESTATE_H
|
#define OPENCS_VIEW_MOUSESTATE_H
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
#include <QPoint>
|
#include <QPoint>
|
||||||
#include <OgreVector3.h>
|
#include <OgreVector3.h>
|
||||||
|
|
||||||
|
@ -43,7 +44,7 @@ namespace CSVRender
|
||||||
MouseStates mMouseState;
|
MouseStates mMouseState;
|
||||||
|
|
||||||
WorldspaceWidget *mParent;
|
WorldspaceWidget *mParent;
|
||||||
CSVWorld::PhysicsSystem *mPhysics; // local copy
|
boost::shared_ptr<CSVWorld::PhysicsSystem> mPhysics;
|
||||||
Ogre::SceneManager *mSceneManager; // local copy
|
Ogre::SceneManager *mSceneManager; // local copy
|
||||||
|
|
||||||
QPoint mOldPos;
|
QPoint mOldPos;
|
||||||
|
|
|
@ -44,11 +44,12 @@ bool CSVRender::Navigation1st::mouseMoved (const QPoint& delta, int mode)
|
||||||
float deltaPitch = getFactor (true) * delta.y();
|
float deltaPitch = getFactor (true) * delta.y();
|
||||||
Ogre::Radian newPitch = oldPitch + Ogre::Degree (deltaPitch);
|
Ogre::Radian newPitch = oldPitch + Ogre::Degree (deltaPitch);
|
||||||
|
|
||||||
Ogre::Radian limit (Ogre::Math::PI/2-0.5);
|
if ((deltaPitch>0 && newPitch<Ogre::Radian(Ogre::Math::PI-0.5)) ||
|
||||||
|
(deltaPitch<0 && newPitch>Ogre::Radian(0.5)))
|
||||||
if ((deltaPitch>0 && newPitch<limit) || (deltaPitch<0 && newPitch>-limit))
|
{
|
||||||
mCamera->pitch (Ogre::Degree (deltaPitch));
|
mCamera->pitch (Ogre::Degree (deltaPitch));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -132,7 +132,7 @@ const CSMWorld::CellRef& CSVRender::Object::getReference() const
|
||||||
}
|
}
|
||||||
|
|
||||||
CSVRender::Object::Object (const CSMWorld::Data& data, Ogre::SceneNode *cellNode,
|
CSVRender::Object::Object (const CSMWorld::Data& data, Ogre::SceneNode *cellNode,
|
||||||
const std::string& id, bool referenceable, CSVWorld::PhysicsSystem *physics,
|
const std::string& id, bool referenceable, boost::shared_ptr<CSVWorld::PhysicsSystem> physics,
|
||||||
bool forceBaseToZero)
|
bool forceBaseToZero)
|
||||||
: mData (data), mBase (0), mForceBaseToZero (forceBaseToZero), mPhysics(physics)
|
: mData (data), mBase (0), mForceBaseToZero (forceBaseToZero), mPhysics(physics)
|
||||||
{
|
{
|
||||||
|
@ -156,6 +156,7 @@ CSVRender::Object::~Object()
|
||||||
{
|
{
|
||||||
clear();
|
clear();
|
||||||
|
|
||||||
|
if(mPhysics) // preview may not have physics enabled
|
||||||
mPhysics->removeObject(mBase->getName());
|
mPhysics->removeObject(mBase->getName());
|
||||||
|
|
||||||
if (mBase)
|
if (mBase)
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#ifndef OPENCS_VIEW_OBJECT_H
|
#ifndef OPENCS_VIEW_OBJECT_H
|
||||||
#define OPENCS_VIEW_OBJECT_H
|
#define OPENCS_VIEW_OBJECT_H
|
||||||
|
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
#include <components/nifogre/ogrenifloader.hpp>
|
#include <components/nifogre/ogrenifloader.hpp>
|
||||||
|
|
||||||
class QModelIndex;
|
class QModelIndex;
|
||||||
|
@ -31,7 +33,7 @@ namespace CSVRender
|
||||||
Ogre::SceneNode *mBase;
|
Ogre::SceneNode *mBase;
|
||||||
NifOgre::ObjectScenePtr mObject;
|
NifOgre::ObjectScenePtr mObject;
|
||||||
bool mForceBaseToZero;
|
bool mForceBaseToZero;
|
||||||
CSVWorld::PhysicsSystem *mPhysics;
|
boost::shared_ptr<CSVWorld::PhysicsSystem> mPhysics;
|
||||||
|
|
||||||
/// Not implemented
|
/// Not implemented
|
||||||
Object (const Object&);
|
Object (const Object&);
|
||||||
|
@ -58,7 +60,8 @@ namespace CSVRender
|
||||||
|
|
||||||
Object (const CSMWorld::Data& data, Ogre::SceneNode *cellNode,
|
Object (const CSMWorld::Data& data, Ogre::SceneNode *cellNode,
|
||||||
const std::string& id, bool referenceable,
|
const std::string& id, bool referenceable,
|
||||||
CSVWorld::PhysicsSystem *physics = NULL, bool forceBaseToZero = false);
|
boost::shared_ptr<CSVWorld::PhysicsSystem> physics = boost::shared_ptr<CSVWorld::PhysicsSystem> (),
|
||||||
|
bool forceBaseToZero = false);
|
||||||
/// \param forceBaseToZero If this is a reference ignore the coordinates and place
|
/// \param forceBaseToZero If this is a reference ignore the coordinates and place
|
||||||
/// it at 0, 0, 0 instead.
|
/// it at 0, 0, 0 instead.
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,10 @@
|
||||||
#include "../../model/world/idtable.hpp"
|
#include "../../model/world/idtable.hpp"
|
||||||
|
|
||||||
#include "../widget/scenetooltoggle.hpp"
|
#include "../widget/scenetooltoggle.hpp"
|
||||||
|
#include "../widget/scenetoolmode.hpp"
|
||||||
|
#include "../widget/scenetooltoggle2.hpp"
|
||||||
|
|
||||||
|
#include "editmode.hpp"
|
||||||
#include "elements.hpp"
|
#include "elements.hpp"
|
||||||
|
|
||||||
bool CSVRender::PagedWorldspaceWidget::adjustCells()
|
bool CSVRender::PagedWorldspaceWidget::adjustCells()
|
||||||
|
@ -109,7 +112,7 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells()
|
||||||
mCells.find (*iter)==mCells.end())
|
mCells.find (*iter)==mCells.end())
|
||||||
{
|
{
|
||||||
Cell *cell = new Cell (mDocument.getData(), getSceneManager(),
|
Cell *cell = new Cell (mDocument.getData(), getSceneManager(),
|
||||||
iter->getId (mWorldspace), getPhysics());
|
iter->getId (mWorldspace), mDocument.getPhysics());
|
||||||
mCells.insert (std::make_pair (*iter, cell));
|
mCells.insert (std::make_pair (*iter, cell));
|
||||||
|
|
||||||
float height = cell->getTerrainHeightAt(Ogre::Vector3(
|
float height = cell->getTerrainHeightAt(Ogre::Vector3(
|
||||||
|
@ -210,6 +213,34 @@ void CSVRender::PagedWorldspaceWidget::mouseDoubleClickEvent (QMouseEvent *event
|
||||||
WorldspaceWidget::mouseDoubleClickEvent(event);
|
WorldspaceWidget::mouseDoubleClickEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSVRender::PagedWorldspaceWidget::addVisibilitySelectorButtons (
|
||||||
|
CSVWidget::SceneToolToggle2 *tool)
|
||||||
|
{
|
||||||
|
WorldspaceWidget::addVisibilitySelectorButtons (tool);
|
||||||
|
tool->addButton (Element_Terrain, "Terrain");
|
||||||
|
tool->addButton (Element_Fog, "Fog", "", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::PagedWorldspaceWidget::addEditModeSelectorButtons (
|
||||||
|
CSVWidget::SceneToolMode *tool)
|
||||||
|
{
|
||||||
|
WorldspaceWidget::addEditModeSelectorButtons (tool);
|
||||||
|
|
||||||
|
/// \todo replace EditMode with suitable subclasses
|
||||||
|
tool->addButton (
|
||||||
|
new EditMode (this, QIcon (":placeholder"), Element_Reference, "Terrain shape editing"),
|
||||||
|
"terrain-shape");
|
||||||
|
tool->addButton (
|
||||||
|
new EditMode (this, QIcon (":placeholder"), Element_Reference, "Terrain texture editing"),
|
||||||
|
"terrain-texture");
|
||||||
|
tool->addButton (
|
||||||
|
new EditMode (this, QIcon (":placeholder"), Element_Reference, "Terrain vertex paint editing"),
|
||||||
|
"terrain-vertex");
|
||||||
|
tool->addButton (
|
||||||
|
new EditMode (this, QIcon (":placeholder"), Element_Reference, "Terrain movement"),
|
||||||
|
"terrain-move");
|
||||||
|
}
|
||||||
|
|
||||||
void CSVRender::PagedWorldspaceWidget::updateOverlay()
|
void CSVRender::PagedWorldspaceWidget::updateOverlay()
|
||||||
{
|
{
|
||||||
if(getCamera()->getViewport())
|
if(getCamera()->getViewport())
|
||||||
|
@ -340,9 +371,12 @@ CSVRender::PagedWorldspaceWidget::~PagedWorldspaceWidget()
|
||||||
delete iter->second;
|
delete iter->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(mOverlayMask)
|
||||||
|
{
|
||||||
removeRenderTargetListener(mOverlayMask);
|
removeRenderTargetListener(mOverlayMask);
|
||||||
delete mOverlayMask;
|
delete mOverlayMask;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CSVRender::PagedWorldspaceWidget::useViewHint (const std::string& hint)
|
void CSVRender::PagedWorldspaceWidget::useViewHint (const std::string& hint)
|
||||||
{
|
{
|
||||||
|
@ -445,21 +479,21 @@ CSVRender::WorldspaceWidget::dropRequirments CSVRender::PagedWorldspaceWidget::g
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int CSVRender::PagedWorldspaceWidget::getElementMask() const
|
unsigned int CSVRender::PagedWorldspaceWidget::getVisibilityMask() const
|
||||||
{
|
{
|
||||||
return WorldspaceWidget::getElementMask() | mControlElements->getSelection();
|
return WorldspaceWidget::getVisibilityMask() | mControlElements->getSelection();
|
||||||
}
|
}
|
||||||
|
|
||||||
CSVWidget::SceneToolToggle *CSVRender::PagedWorldspaceWidget::makeControlVisibilitySelector (
|
CSVWidget::SceneToolToggle *CSVRender::PagedWorldspaceWidget::makeControlVisibilitySelector (
|
||||||
CSVWidget::SceneToolbar *parent)
|
CSVWidget::SceneToolbar *parent)
|
||||||
{
|
{
|
||||||
mControlElements = new CSVWidget::SceneToolToggle (parent,
|
mControlElements = new CSVWidget::SceneToolToggle (parent,
|
||||||
"Controls & Guides Visibility", ":door.png");
|
"Controls & Guides Visibility", ":placeholder");
|
||||||
|
|
||||||
mControlElements->addButton (":activator.png", Element_CellMarker, ":activator.png",
|
mControlElements->addButton (":placeholder", Element_CellMarker, ":placeholder",
|
||||||
"Cell marker");
|
"Cell marker");
|
||||||
mControlElements->addButton (":armor.png", Element_CellArrow, ":armor.png", "Cell arrows");
|
mControlElements->addButton (":placeholder", Element_CellArrow, ":placeholder", "Cell arrows");
|
||||||
mControlElements->addButton (":armor.png", Element_CellBorder, ":armor.png", "Cell border");
|
mControlElements->addButton (":placeholder", Element_CellBorder, ":placeholder", "Cell border");
|
||||||
|
|
||||||
mControlElements->setSelection (0xffffffff);
|
mControlElements->setSelection (0xffffffff);
|
||||||
|
|
||||||
|
|
|
@ -8,9 +8,13 @@
|
||||||
#include "worldspacewidget.hpp"
|
#include "worldspacewidget.hpp"
|
||||||
#include "cell.hpp"
|
#include "cell.hpp"
|
||||||
|
|
||||||
|
namespace CSVWidget
|
||||||
|
{
|
||||||
|
class SceneToolToggle;
|
||||||
|
}
|
||||||
|
|
||||||
namespace CSVRender
|
namespace CSVRender
|
||||||
{
|
{
|
||||||
|
|
||||||
class TextOverlay;
|
class TextOverlay;
|
||||||
class OverlayMask;
|
class OverlayMask;
|
||||||
|
|
||||||
|
@ -75,10 +79,14 @@ namespace CSVRender
|
||||||
virtual CSVWidget::SceneToolToggle *makeControlVisibilitySelector (
|
virtual CSVWidget::SceneToolToggle *makeControlVisibilitySelector (
|
||||||
CSVWidget::SceneToolbar *parent);
|
CSVWidget::SceneToolbar *parent);
|
||||||
|
|
||||||
virtual unsigned int getElementMask() const;
|
virtual unsigned int getVisibilityMask() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
virtual void addVisibilitySelectorButtons (CSVWidget::SceneToolToggle2 *tool);
|
||||||
|
|
||||||
|
virtual void addEditModeSelectorButtons (CSVWidget::SceneToolMode *tool);
|
||||||
|
|
||||||
virtual void updateOverlay();
|
virtual void updateOverlay();
|
||||||
|
|
||||||
virtual void mousePressEvent (QMouseEvent *event);
|
virtual void mousePressEvent (QMouseEvent *event);
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
CSVRender::PreviewWidget::PreviewWidget (CSMWorld::Data& data,
|
CSVRender::PreviewWidget::PreviewWidget (CSMWorld::Data& data,
|
||||||
const std::string& id, bool referenceable, QWidget *parent)
|
const std::string& id, bool referenceable, QWidget *parent)
|
||||||
: SceneWidget (parent), mData (data),
|
: SceneWidget (parent), mData (data),
|
||||||
mObject (data, getSceneManager()->getRootSceneNode(), id, referenceable, NULL, true)
|
mObject (data, getSceneManager()->getRootSceneNode(), id, referenceable, boost::shared_ptr<CSVWorld::PhysicsSystem>(), true)
|
||||||
{
|
{
|
||||||
setNavigation (&mOrbit);
|
setNavigation (&mOrbit);
|
||||||
|
|
||||||
|
|
|
@ -79,7 +79,7 @@ TextOverlay::TextOverlay(const Ogre::MovableObject* obj, const Ogre::Camera* cam
|
||||||
pixelBuffer->lock(Ogre::HardwareBuffer::HBL_NORMAL);
|
pixelBuffer->lock(Ogre::HardwareBuffer::HBL_NORMAL);
|
||||||
const Ogre::PixelBox& pixelBox = pixelBuffer->getCurrentLock();
|
const Ogre::PixelBox& pixelBox = pixelBuffer->getCurrentLock();
|
||||||
|
|
||||||
uint8_t* pDest = static_cast<uint8_t*>(pixelBox.data);
|
Ogre::uint8* pDest = static_cast<Ogre::uint8*>(pixelBox.data);
|
||||||
|
|
||||||
// Fill in some pixel data. This will give a semi-transparent blue,
|
// Fill in some pixel data. This will give a semi-transparent blue,
|
||||||
// but this is of course dependent on the chosen pixel format.
|
// but this is of course dependent on the chosen pixel format.
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include "../../model/world/tablemimedata.hpp"
|
#include "../../model/world/tablemimedata.hpp"
|
||||||
|
|
||||||
#include "../widget/scenetooltoggle.hpp"
|
#include "../widget/scenetooltoggle.hpp"
|
||||||
|
#include "../widget/scenetooltoggle2.hpp"
|
||||||
|
|
||||||
#include "elements.hpp"
|
#include "elements.hpp"
|
||||||
|
|
||||||
|
@ -32,14 +33,6 @@ void CSVRender::UnpagedWorldspaceWidget::update()
|
||||||
flagAsModified();
|
flagAsModified();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVRender::UnpagedWorldspaceWidget::addVisibilitySelectorButtons (
|
|
||||||
CSVWidget::SceneToolToggle *tool)
|
|
||||||
{
|
|
||||||
WorldspaceWidget::addVisibilitySelectorButtons (tool);
|
|
||||||
|
|
||||||
tool->addButton (":armor.png", Element_Fog, ":armor.png", "Fog");
|
|
||||||
}
|
|
||||||
|
|
||||||
CSVRender::UnpagedWorldspaceWidget::UnpagedWorldspaceWidget (const std::string& cellId, CSMDoc::Document& document, QWidget* parent)
|
CSVRender::UnpagedWorldspaceWidget::UnpagedWorldspaceWidget (const std::string& cellId, CSMDoc::Document& document, QWidget* parent)
|
||||||
: WorldspaceWidget (document, parent), mCellId (cellId)
|
: WorldspaceWidget (document, parent), mCellId (cellId)
|
||||||
{
|
{
|
||||||
|
@ -56,7 +49,7 @@ CSVRender::UnpagedWorldspaceWidget::UnpagedWorldspaceWidget (const std::string&
|
||||||
|
|
||||||
update();
|
update();
|
||||||
|
|
||||||
mCell.reset (new Cell (document.getData(), getSceneManager(), mCellId, getPhysics()));
|
mCell.reset (new Cell (document.getData(), getSceneManager(), mCellId, document.getPhysics()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVRender::UnpagedWorldspaceWidget::cellDataChanged (const QModelIndex& topLeft,
|
void CSVRender::UnpagedWorldspaceWidget::cellDataChanged (const QModelIndex& topLeft,
|
||||||
|
@ -98,7 +91,7 @@ bool CSVRender::UnpagedWorldspaceWidget::handleDrop (const std::vector<CSMWorld:
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
mCellId = data.begin()->getId();
|
mCellId = data.begin()->getId();
|
||||||
mCell.reset (new Cell (getDocument().getData(), getSceneManager(), mCellId, getPhysics()));
|
mCell.reset (new Cell (getDocument().getData(), getSceneManager(), mCellId, getDocument().getPhysics()));
|
||||||
|
|
||||||
update();
|
update();
|
||||||
emit cellChanged(*data.begin());
|
emit cellChanged(*data.begin());
|
||||||
|
@ -160,6 +153,14 @@ void CSVRender::UnpagedWorldspaceWidget::referenceAdded (const QModelIndex& pare
|
||||||
flagAsModified();
|
flagAsModified();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSVRender::UnpagedWorldspaceWidget::addVisibilitySelectorButtons (
|
||||||
|
CSVWidget::SceneToolToggle2 *tool)
|
||||||
|
{
|
||||||
|
WorldspaceWidget::addVisibilitySelectorButtons (tool);
|
||||||
|
tool->addButton (Element_Terrain, "Terrain", "", true);
|
||||||
|
tool->addButton (Element_Fog, "Fog");
|
||||||
|
}
|
||||||
|
|
||||||
std::string CSVRender::UnpagedWorldspaceWidget::getStartupInstruction()
|
std::string CSVRender::UnpagedWorldspaceWidget::getStartupInstruction()
|
||||||
{
|
{
|
||||||
Ogre::Vector3 position = getCamera()->getPosition();
|
Ogre::Vector3 position = getCamera()->getPosition();
|
||||||
|
|
|
@ -32,10 +32,6 @@ namespace CSVRender
|
||||||
|
|
||||||
void update();
|
void update();
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
virtual void addVisibilitySelectorButtons (CSVWidget::SceneToolToggle *tool);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
UnpagedWorldspaceWidget (const std::string& cellId, CSMDoc::Document& document,
|
UnpagedWorldspaceWidget (const std::string& cellId, CSMDoc::Document& document,
|
||||||
|
@ -64,6 +60,10 @@ namespace CSVRender
|
||||||
|
|
||||||
virtual std::string getStartupInstruction();
|
virtual std::string getStartupInstruction();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
virtual void addVisibilitySelectorButtons (CSVWidget::SceneToolToggle2 *tool);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|
||||||
void cellDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight);
|
void cellDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight);
|
||||||
|
|
|
@ -13,16 +13,17 @@
|
||||||
#include "../../model/world/idtable.hpp"
|
#include "../../model/world/idtable.hpp"
|
||||||
|
|
||||||
#include "../widget/scenetoolmode.hpp"
|
#include "../widget/scenetoolmode.hpp"
|
||||||
#include "../widget/scenetooltoggle.hpp"
|
#include "../widget/scenetooltoggle2.hpp"
|
||||||
#include "../widget/scenetoolrun.hpp"
|
#include "../widget/scenetoolrun.hpp"
|
||||||
|
|
||||||
#include "../world/physicsmanager.hpp"
|
|
||||||
#include "../world/physicssystem.hpp"
|
#include "../world/physicssystem.hpp"
|
||||||
|
|
||||||
#include "elements.hpp"
|
#include "elements.hpp"
|
||||||
|
#include "editmode.hpp"
|
||||||
|
|
||||||
CSVRender::WorldspaceWidget::WorldspaceWidget (CSMDoc::Document& document, QWidget* parent)
|
CSVRender::WorldspaceWidget::WorldspaceWidget (CSMDoc::Document& document, QWidget* parent)
|
||||||
: SceneWidget (parent), mDocument(document), mSceneElements(0), mRun(0), mPhysics(0), mMouse(0)
|
: SceneWidget (parent), mDocument(document), mSceneElements(0), mRun(0), mPhysics(boost::shared_ptr<CSVWorld::PhysicsSystem>()), mMouse(0),
|
||||||
|
mInteractionMask (0)
|
||||||
{
|
{
|
||||||
setAcceptDrops(true);
|
setAcceptDrops(true);
|
||||||
|
|
||||||
|
@ -54,9 +55,7 @@ CSVRender::WorldspaceWidget::WorldspaceWidget (CSMDoc::Document& document, QWidg
|
||||||
connect (debugProfiles, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)),
|
connect (debugProfiles, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)),
|
||||||
this, SLOT (debugProfileAboutToBeRemoved (const QModelIndex&, int, int)));
|
this, SLOT (debugProfileAboutToBeRemoved (const QModelIndex&, int, int)));
|
||||||
|
|
||||||
// associate WorldSpaceWidgets (and their SceneManagers) with Documents
|
mPhysics = document.getPhysics(); // create physics if one doesn't exist
|
||||||
// then create physics if there is a new document
|
|
||||||
mPhysics = CSVWorld::PhysicsManager::instance()->addSceneWidget(document, this);
|
|
||||||
mPhysics->addSceneManager(getSceneManager(), this);
|
mPhysics->addSceneManager(getSceneManager(), this);
|
||||||
mMouse = new MouseState(this);
|
mMouse = new MouseState(this);
|
||||||
}
|
}
|
||||||
|
@ -65,7 +64,6 @@ CSVRender::WorldspaceWidget::~WorldspaceWidget ()
|
||||||
{
|
{
|
||||||
delete mMouse;
|
delete mMouse;
|
||||||
mPhysics->removeSceneManager(getSceneManager());
|
mPhysics->removeSceneManager(getSceneManager());
|
||||||
CSVWorld::PhysicsManager::instance()->removeSceneWidget(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVRender::WorldspaceWidget::selectNavigationMode (const std::string& mode)
|
void CSVRender::WorldspaceWidget::selectNavigationMode (const std::string& mode)
|
||||||
|
@ -125,10 +123,10 @@ CSVWidget::SceneToolMode *CSVRender::WorldspaceWidget::makeNavigationSelector (
|
||||||
return tool;
|
return tool;
|
||||||
}
|
}
|
||||||
|
|
||||||
CSVWidget::SceneToolToggle *CSVRender::WorldspaceWidget::makeSceneVisibilitySelector (CSVWidget::SceneToolbar *parent)
|
CSVWidget::SceneToolToggle2 *CSVRender::WorldspaceWidget::makeSceneVisibilitySelector (CSVWidget::SceneToolbar *parent)
|
||||||
{
|
{
|
||||||
mSceneElements= new CSVWidget::SceneToolToggle (parent,
|
mSceneElements = new CSVWidget::SceneToolToggle2 (parent,
|
||||||
"Scene Element Visibility", ":door.png");
|
"Scene Element Visibility", ":scenetoolbar/scene-view-c", ":scenetoolbar/scene-view-");
|
||||||
|
|
||||||
addVisibilitySelectorButtons (mSceneElements);
|
addVisibilitySelectorButtons (mSceneElements);
|
||||||
|
|
||||||
|
@ -170,7 +168,7 @@ CSVWidget::SceneToolRun *CSVRender::WorldspaceWidget::makeRunTool (
|
||||||
std::sort (profiles.begin(), profiles.end());
|
std::sort (profiles.begin(), profiles.end());
|
||||||
|
|
||||||
mRun = new CSVWidget::SceneToolRun (parent, "Run OpenMW from the current camera position",
|
mRun = new CSVWidget::SceneToolRun (parent, "Run OpenMW from the current camera position",
|
||||||
":door.png", ":faction.png", profiles);
|
":scenetoolbar/play", profiles);
|
||||||
|
|
||||||
connect (mRun, SIGNAL (runRequest (const std::string&)),
|
connect (mRun, SIGNAL (runRequest (const std::string&)),
|
||||||
this, SLOT (runRequest (const std::string&)));
|
this, SLOT (runRequest (const std::string&)));
|
||||||
|
@ -178,6 +176,16 @@ CSVWidget::SceneToolRun *CSVRender::WorldspaceWidget::makeRunTool (
|
||||||
return mRun;
|
return mRun;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CSVWidget::SceneToolMode *CSVRender::WorldspaceWidget::makeEditModeSelector (
|
||||||
|
CSVWidget::SceneToolbar *parent)
|
||||||
|
{
|
||||||
|
CSVWidget::SceneToolMode *tool = new CSVWidget::SceneToolMode (parent, "Edit Mode");
|
||||||
|
|
||||||
|
addEditModeSelectorButtons (tool);
|
||||||
|
|
||||||
|
return tool;
|
||||||
|
}
|
||||||
|
|
||||||
CSVRender::WorldspaceWidget::DropType CSVRender::WorldspaceWidget::getDropType (
|
CSVRender::WorldspaceWidget::DropType CSVRender::WorldspaceWidget::getDropType (
|
||||||
const std::vector< CSMWorld::UniversalId >& data)
|
const std::vector< CSMWorld::UniversalId >& data)
|
||||||
{
|
{
|
||||||
|
@ -232,18 +240,38 @@ bool CSVRender::WorldspaceWidget::handleDrop (const std::vector<CSMWorld::Univer
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int CSVRender::WorldspaceWidget::getElementMask() const
|
unsigned int CSVRender::WorldspaceWidget::getVisibilityMask() const
|
||||||
{
|
{
|
||||||
return mSceneElements->getSelection();
|
return mSceneElements->getSelection();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVRender::WorldspaceWidget::addVisibilitySelectorButtons (
|
void CSVRender::WorldspaceWidget::setInteractionMask (unsigned int mask)
|
||||||
CSVWidget::SceneToolToggle *tool)
|
|
||||||
{
|
{
|
||||||
tool->addButton (":activator.png", Element_Reference, ":activator.png", "References");
|
mInteractionMask = mask | Element_CellMarker | Element_CellArrow;
|
||||||
tool->addButton (":armor.png", Element_Terrain, ":armor.png", "Terrain");
|
}
|
||||||
tool->addButton (":armor.png", Element_Water, ":armor.png", "Water");
|
|
||||||
tool->addButton (":armor.png", Element_Pathgrid, ":armor.png", "Pathgrid");
|
unsigned int CSVRender::WorldspaceWidget::getInteractionMask() const
|
||||||
|
{
|
||||||
|
return mInteractionMask & getVisibilityMask();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::WorldspaceWidget::addVisibilitySelectorButtons (
|
||||||
|
CSVWidget::SceneToolToggle2 *tool)
|
||||||
|
{
|
||||||
|
tool->addButton (Element_Reference, "References");
|
||||||
|
tool->addButton (Element_Water, "Water");
|
||||||
|
tool->addButton (Element_Pathgrid, "Pathgrid");
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::WorldspaceWidget::addEditModeSelectorButtons (CSVWidget::SceneToolMode *tool)
|
||||||
|
{
|
||||||
|
/// \todo replace EditMode with suitable subclasses
|
||||||
|
tool->addButton (
|
||||||
|
new EditMode (this, QIcon (":placeholder"), Element_Reference, "Reference editing"),
|
||||||
|
"object");
|
||||||
|
tool->addButton (
|
||||||
|
new EditMode (this, QIcon (":placeholder"), Element_Pathgrid, "Pathgrid editing"),
|
||||||
|
"pathgrid");
|
||||||
}
|
}
|
||||||
|
|
||||||
CSMDoc::Document& CSVRender::WorldspaceWidget::getDocument()
|
CSMDoc::Document& CSVRender::WorldspaceWidget::getDocument()
|
||||||
|
@ -327,7 +355,7 @@ void CSVRender::WorldspaceWidget::debugProfileAboutToBeRemoved (const QModelInde
|
||||||
|
|
||||||
void CSVRender::WorldspaceWidget::elementSelectionChanged()
|
void CSVRender::WorldspaceWidget::elementSelectionChanged()
|
||||||
{
|
{
|
||||||
setVisibilityMask (getElementMask());
|
setVisibilityMask (getVisibilityMask());
|
||||||
flagAsModified();
|
flagAsModified();
|
||||||
updateOverlay();
|
updateOverlay();
|
||||||
}
|
}
|
||||||
|
@ -336,12 +364,6 @@ void CSVRender::WorldspaceWidget::updateOverlay()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
CSVWorld::PhysicsSystem *CSVRender::WorldspaceWidget::getPhysics()
|
|
||||||
{
|
|
||||||
assert(mPhysics);
|
|
||||||
return mPhysics;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSVRender::WorldspaceWidget::mouseMoveEvent (QMouseEvent *event)
|
void CSVRender::WorldspaceWidget::mouseMoveEvent (QMouseEvent *event)
|
||||||
{
|
{
|
||||||
if(event->buttons() & Qt::RightButton)
|
if(event->buttons() & Qt::RightButton)
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#ifndef OPENCS_VIEW_WORLDSPACEWIDGET_H
|
#ifndef OPENCS_VIEW_WORLDSPACEWIDGET_H
|
||||||
#define OPENCS_VIEW_WORLDSPACEWIDGET_H
|
#define OPENCS_VIEW_WORLDSPACEWIDGET_H
|
||||||
|
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
#include "scenewidget.hpp"
|
#include "scenewidget.hpp"
|
||||||
#include "mousestate.hpp"
|
#include "mousestate.hpp"
|
||||||
|
|
||||||
|
@ -18,7 +20,7 @@ namespace CSMWorld
|
||||||
namespace CSVWidget
|
namespace CSVWidget
|
||||||
{
|
{
|
||||||
class SceneToolMode;
|
class SceneToolMode;
|
||||||
class SceneToolToggle;
|
class SceneToolToggle2;
|
||||||
class SceneToolbar;
|
class SceneToolbar;
|
||||||
class SceneToolRun;
|
class SceneToolRun;
|
||||||
}
|
}
|
||||||
|
@ -37,11 +39,12 @@ namespace CSVRender
|
||||||
CSVRender::Navigation1st m1st;
|
CSVRender::Navigation1st m1st;
|
||||||
CSVRender::NavigationFree mFree;
|
CSVRender::NavigationFree mFree;
|
||||||
CSVRender::NavigationOrbit mOrbit;
|
CSVRender::NavigationOrbit mOrbit;
|
||||||
CSVWidget::SceneToolToggle *mSceneElements;
|
CSVWidget::SceneToolToggle2 *mSceneElements;
|
||||||
CSVWidget::SceneToolRun *mRun;
|
CSVWidget::SceneToolRun *mRun;
|
||||||
CSMDoc::Document& mDocument;
|
CSMDoc::Document& mDocument;
|
||||||
CSVWorld::PhysicsSystem *mPhysics;
|
boost::shared_ptr<CSVWorld::PhysicsSystem> mPhysics;
|
||||||
MouseState *mMouse;
|
MouseState *mMouse;
|
||||||
|
unsigned int mInteractionMask;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -70,13 +73,17 @@ namespace CSVRender
|
||||||
|
|
||||||
/// \attention The created tool is not added to the toolbar (via addTool). Doing
|
/// \attention The created tool is not added to the toolbar (via addTool). Doing
|
||||||
/// that is the responsibility of the calling function.
|
/// that is the responsibility of the calling function.
|
||||||
CSVWidget::SceneToolToggle *makeSceneVisibilitySelector (
|
CSVWidget::SceneToolToggle2 *makeSceneVisibilitySelector (
|
||||||
CSVWidget::SceneToolbar *parent);
|
CSVWidget::SceneToolbar *parent);
|
||||||
|
|
||||||
/// \attention The created tool is not added to the toolbar (via addTool). Doing
|
/// \attention The created tool is not added to the toolbar (via addTool). Doing
|
||||||
/// that is the responsibility of the calling function.
|
/// that is the responsibility of the calling function.
|
||||||
CSVWidget::SceneToolRun *makeRunTool (CSVWidget::SceneToolbar *parent);
|
CSVWidget::SceneToolRun *makeRunTool (CSVWidget::SceneToolbar *parent);
|
||||||
|
|
||||||
|
/// \attention The created tool is not added to the toolbar (via addTool). Doing
|
||||||
|
/// that is the responsibility of the calling function.
|
||||||
|
CSVWidget::SceneToolMode *makeEditModeSelector (CSVWidget::SceneToolbar *parent);
|
||||||
|
|
||||||
void selectDefaultNavigationMode();
|
void selectDefaultNavigationMode();
|
||||||
|
|
||||||
static DropType getDropType(const std::vector<CSMWorld::UniversalId>& data);
|
static DropType getDropType(const std::vector<CSMWorld::UniversalId>& data);
|
||||||
|
@ -90,18 +97,26 @@ namespace CSVRender
|
||||||
virtual bool handleDrop (const std::vector<CSMWorld::UniversalId>& data,
|
virtual bool handleDrop (const std::vector<CSMWorld::UniversalId>& data,
|
||||||
DropType type);
|
DropType type);
|
||||||
|
|
||||||
virtual unsigned int getElementMask() const;
|
virtual unsigned int getVisibilityMask() const;
|
||||||
|
|
||||||
|
/// \note This function will implicitly add elements that are independent of the
|
||||||
|
/// selected edit mode.
|
||||||
|
virtual void setInteractionMask (unsigned int mask);
|
||||||
|
|
||||||
|
/// \note This function will only return those elements that are both visible and
|
||||||
|
/// marked for interaction.
|
||||||
|
unsigned int getInteractionMask() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
virtual void addVisibilitySelectorButtons (CSVWidget::SceneToolToggle *tool);
|
virtual void addVisibilitySelectorButtons (CSVWidget::SceneToolToggle2 *tool);
|
||||||
|
|
||||||
|
virtual void addEditModeSelectorButtons (CSVWidget::SceneToolMode *tool);
|
||||||
|
|
||||||
CSMDoc::Document& getDocument();
|
CSMDoc::Document& getDocument();
|
||||||
|
|
||||||
virtual void updateOverlay();
|
virtual void updateOverlay();
|
||||||
|
|
||||||
CSVWorld::PhysicsSystem *getPhysics();
|
|
||||||
|
|
||||||
virtual void mouseMoveEvent (QMouseEvent *event);
|
virtual void mouseMoveEvent (QMouseEvent *event);
|
||||||
virtual void mousePressEvent (QMouseEvent *event);
|
virtual void mousePressEvent (QMouseEvent *event);
|
||||||
virtual void mouseReleaseEvent (QMouseEvent *event);
|
virtual void mouseReleaseEvent (QMouseEvent *event);
|
||||||
|
|
|
@ -1,31 +1,15 @@
|
||||||
|
|
||||||
#include "reportsubview.hpp"
|
#include "reportsubview.hpp"
|
||||||
|
|
||||||
#include <QTableView>
|
#include "reporttable.hpp"
|
||||||
#include <QHeaderView>
|
|
||||||
|
|
||||||
#include "../../model/tools/reportmodel.hpp"
|
|
||||||
|
|
||||||
#include "../../view/world/idtypedelegate.hpp"
|
|
||||||
|
|
||||||
CSVTools::ReportSubView::ReportSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document)
|
CSVTools::ReportSubView::ReportSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document)
|
||||||
: CSVDoc::SubView (id), mModel (document.getReport (id))
|
: CSVDoc::SubView (id)
|
||||||
{
|
{
|
||||||
setWidget (mTable = new QTableView (this));
|
setWidget (mTable = new ReportTable (document, id, this));
|
||||||
mTable->setModel (mModel);
|
|
||||||
|
|
||||||
mTable->horizontalHeader()->setResizeMode (QHeaderView::Interactive);
|
connect (mTable, SIGNAL (editRequest (const CSMWorld::UniversalId&, const std::string&)),
|
||||||
mTable->verticalHeader()->hide();
|
SIGNAL (focusId (const CSMWorld::UniversalId&, const std::string&)));
|
||||||
mTable->setSortingEnabled (true);
|
|
||||||
mTable->setSelectionBehavior (QAbstractItemView::SelectRows);
|
|
||||||
mTable->setSelectionMode (QAbstractItemView::ExtendedSelection);
|
|
||||||
|
|
||||||
mIdTypeDelegate = CSVWorld::IdTypeDelegateFactory().makeDelegate (
|
|
||||||
document, this);
|
|
||||||
|
|
||||||
mTable->setItemDelegateForColumn (0, mIdTypeDelegate);
|
|
||||||
|
|
||||||
connect (mTable, SIGNAL (doubleClicked (const QModelIndex&)), this, SLOT (show (const QModelIndex&)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVTools::ReportSubView::setEditLock (bool locked)
|
void CSVTools::ReportSubView::setEditLock (bool locked)
|
||||||
|
@ -33,13 +17,7 @@ void CSVTools::ReportSubView::setEditLock (bool locked)
|
||||||
// ignored. We don't change document state anyway.
|
// ignored. We don't change document state anyway.
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVTools::ReportSubView::updateUserSetting
|
void CSVTools::ReportSubView::updateUserSetting (const QString &name, const QStringList &list)
|
||||||
(const QString &name, const QStringList &list)
|
|
||||||
{
|
{
|
||||||
mIdTypeDelegate->updateUserSetting (name, list);
|
mTable->updateUserSetting (name, list);
|
||||||
}
|
|
||||||
|
|
||||||
void CSVTools::ReportSubView::show (const QModelIndex& index)
|
|
||||||
{
|
|
||||||
focusId (mModel->getUniversalId (index.row()), "");
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,27 +11,15 @@ namespace CSMDoc
|
||||||
class Document;
|
class Document;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace CSMTools
|
|
||||||
{
|
|
||||||
class ReportModel;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace CSVWorld
|
|
||||||
{
|
|
||||||
class CommandDelegate;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace CSVTools
|
namespace CSVTools
|
||||||
{
|
{
|
||||||
class Table;
|
class ReportTable;
|
||||||
|
|
||||||
class ReportSubView : public CSVDoc::SubView
|
class ReportSubView : public CSVDoc::SubView
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
CSMTools::ReportModel *mModel;
|
ReportTable *mTable;
|
||||||
QTableView *mTable;
|
|
||||||
CSVWorld::CommandDelegate *mIdTypeDelegate;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -39,12 +27,7 @@ namespace CSVTools
|
||||||
|
|
||||||
virtual void setEditLock (bool locked);
|
virtual void setEditLock (bool locked);
|
||||||
|
|
||||||
virtual void updateUserSetting
|
virtual void updateUserSetting (const QString &, const QStringList &);
|
||||||
(const QString &, const QStringList &);
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
|
|
||||||
void show (const QModelIndex& index);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
136
apps/opencs/view/tools/reporttable.cpp
Normal file
136
apps/opencs/view/tools/reporttable.cpp
Normal file
|
@ -0,0 +1,136 @@
|
||||||
|
|
||||||
|
#include "reporttable.hpp"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include <QHeaderView>
|
||||||
|
#include <QAction>
|
||||||
|
#include <QMenu>
|
||||||
|
|
||||||
|
#include "../../model/tools/reportmodel.hpp"
|
||||||
|
|
||||||
|
#include "../../view/world/idtypedelegate.hpp"
|
||||||
|
|
||||||
|
void CSVTools::ReportTable::contextMenuEvent (QContextMenuEvent *event)
|
||||||
|
{
|
||||||
|
QModelIndexList selectedRows = selectionModel()->selectedRows();
|
||||||
|
|
||||||
|
// create context menu
|
||||||
|
QMenu menu (this);
|
||||||
|
|
||||||
|
if (!selectedRows.empty())
|
||||||
|
{
|
||||||
|
menu.addAction (mShowAction);
|
||||||
|
menu.addAction (mRemoveAction);
|
||||||
|
}
|
||||||
|
|
||||||
|
menu.exec (event->globalPos());
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVTools::ReportTable::mouseMoveEvent (QMouseEvent *event)
|
||||||
|
{
|
||||||
|
if (event->buttons() & Qt::LeftButton)
|
||||||
|
startDrag (*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVTools::ReportTable::mouseDoubleClickEvent (QMouseEvent *event)
|
||||||
|
{
|
||||||
|
Qt::KeyboardModifiers modifiers =
|
||||||
|
event->modifiers() & (Qt::ShiftModifier | Qt::ControlModifier);
|
||||||
|
|
||||||
|
QModelIndex index = currentIndex();
|
||||||
|
|
||||||
|
selectionModel()->select (index,
|
||||||
|
QItemSelectionModel::Clear | QItemSelectionModel::Select | QItemSelectionModel::Rows);
|
||||||
|
|
||||||
|
switch (modifiers)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
|
||||||
|
event->accept();
|
||||||
|
showSelection();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Qt::ShiftModifier:
|
||||||
|
|
||||||
|
event->accept();
|
||||||
|
removeSelection();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Qt::ControlModifier:
|
||||||
|
|
||||||
|
event->accept();
|
||||||
|
showSelection();
|
||||||
|
removeSelection();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CSVTools::ReportTable::ReportTable (CSMDoc::Document& document,
|
||||||
|
const CSMWorld::UniversalId& id, QWidget *parent)
|
||||||
|
: CSVWorld::DragRecordTable (document, parent), mModel (document.getReport (id))
|
||||||
|
{
|
||||||
|
horizontalHeader()->setResizeMode (QHeaderView::Interactive);
|
||||||
|
verticalHeader()->hide();
|
||||||
|
setSortingEnabled (true);
|
||||||
|
setSelectionBehavior (QAbstractItemView::SelectRows);
|
||||||
|
setSelectionMode (QAbstractItemView::ExtendedSelection);
|
||||||
|
|
||||||
|
setModel (mModel);
|
||||||
|
setColumnHidden (2, true);
|
||||||
|
|
||||||
|
mIdTypeDelegate = CSVWorld::IdTypeDelegateFactory().makeDelegate (
|
||||||
|
document, this);
|
||||||
|
|
||||||
|
setItemDelegateForColumn (0, mIdTypeDelegate);
|
||||||
|
|
||||||
|
mShowAction = new QAction (tr ("Show"), this);
|
||||||
|
connect (mShowAction, SIGNAL (triggered()), this, SLOT (showSelection()));
|
||||||
|
addAction (mShowAction);
|
||||||
|
|
||||||
|
mRemoveAction = new QAction (tr ("Remove from list"), this);
|
||||||
|
connect (mRemoveAction, SIGNAL (triggered()), this, SLOT (removeSelection()));
|
||||||
|
addAction (mRemoveAction);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<CSMWorld::UniversalId> CSVTools::ReportTable::getDraggedRecords() const
|
||||||
|
{
|
||||||
|
std::vector<CSMWorld::UniversalId> ids;
|
||||||
|
|
||||||
|
QModelIndexList selectedRows = selectionModel()->selectedRows();
|
||||||
|
|
||||||
|
for (QModelIndexList::const_iterator iter (selectedRows.begin()); iter!=selectedRows.end();
|
||||||
|
++iter)
|
||||||
|
{
|
||||||
|
ids.push_back (mModel->getUniversalId (iter->row()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return ids;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVTools::ReportTable::updateUserSetting (const QString& name, const QStringList& list)
|
||||||
|
{
|
||||||
|
mIdTypeDelegate->updateUserSetting (name, list);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVTools::ReportTable::showSelection()
|
||||||
|
{
|
||||||
|
QModelIndexList selectedRows = selectionModel()->selectedRows();
|
||||||
|
|
||||||
|
for (QModelIndexList::const_iterator iter (selectedRows.begin()); iter!=selectedRows.end();
|
||||||
|
++iter)
|
||||||
|
emit editRequest (mModel->getUniversalId (iter->row()), mModel->getHint (iter->row()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVTools::ReportTable::removeSelection()
|
||||||
|
{
|
||||||
|
QModelIndexList selectedRows = selectionModel()->selectedRows();
|
||||||
|
|
||||||
|
std::reverse (selectedRows.begin(), selectedRows.end());
|
||||||
|
|
||||||
|
for (QModelIndexList::const_iterator iter (selectedRows.begin()); iter!=selectedRows.end();
|
||||||
|
++iter)
|
||||||
|
mModel->removeRows (iter->row(), 1);
|
||||||
|
|
||||||
|
selectionModel()->clear();
|
||||||
|
}
|
58
apps/opencs/view/tools/reporttable.hpp
Normal file
58
apps/opencs/view/tools/reporttable.hpp
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
#ifndef CSV_TOOLS_REPORTTABLE_H
|
||||||
|
#define CSV_TOOLS_REPORTTABLE_H
|
||||||
|
|
||||||
|
#include "../world/dragrecordtable.hpp"
|
||||||
|
|
||||||
|
class QAction;
|
||||||
|
|
||||||
|
namespace CSMTools
|
||||||
|
{
|
||||||
|
class ReportModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace CSVWorld
|
||||||
|
{
|
||||||
|
class CommandDelegate;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace CSVTools
|
||||||
|
{
|
||||||
|
class ReportTable : public CSVWorld::DragRecordTable
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
CSMTools::ReportModel *mModel;
|
||||||
|
CSVWorld::CommandDelegate *mIdTypeDelegate;
|
||||||
|
QAction *mShowAction;
|
||||||
|
QAction *mRemoveAction;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void contextMenuEvent (QContextMenuEvent *event);
|
||||||
|
|
||||||
|
void mouseMoveEvent (QMouseEvent *event);
|
||||||
|
|
||||||
|
virtual void mouseDoubleClickEvent (QMouseEvent *event);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
ReportTable (CSMDoc::Document& document, const CSMWorld::UniversalId& id,
|
||||||
|
QWidget *parent = 0);
|
||||||
|
|
||||||
|
virtual std::vector<CSMWorld::UniversalId> getDraggedRecords() const;
|
||||||
|
|
||||||
|
void updateUserSetting (const QString& name, const QStringList& list);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
|
||||||
|
void showSelection();
|
||||||
|
|
||||||
|
void removeSelection();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
void editRequest (const CSMWorld::UniversalId& id, const std::string& hint);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
10
apps/opencs/view/widget/modebutton.cpp
Normal file
10
apps/opencs/view/widget/modebutton.cpp
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
|
||||||
|
#include "modebutton.hpp"
|
||||||
|
|
||||||
|
CSVWidget::ModeButton::ModeButton (const QIcon& icon, const QString& tooltip, QWidget *parent)
|
||||||
|
: PushButton (icon, Type_Mode, tooltip, parent)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void CSVWidget::ModeButton::activate (SceneToolbar *toolbar) {}
|
||||||
|
|
||||||
|
void CSVWidget::ModeButton::deactivate (SceneToolbar *toolbar) {}
|
28
apps/opencs/view/widget/modebutton.hpp
Normal file
28
apps/opencs/view/widget/modebutton.hpp
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
#ifndef CSV_WIDGET_MODEBUTTON_H
|
||||||
|
#define CSV_WIDGET_MODEBUTTON_H
|
||||||
|
|
||||||
|
#include "pushbutton.hpp"
|
||||||
|
|
||||||
|
namespace CSVWidget
|
||||||
|
{
|
||||||
|
class SceneToolbar;
|
||||||
|
|
||||||
|
/// \brief Specialist PushButton of Type_Mode for use in SceneToolMode
|
||||||
|
class ModeButton : public PushButton
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
ModeButton (const QIcon& icon, const QString& tooltip = "",
|
||||||
|
QWidget *parent = 0);
|
||||||
|
|
||||||
|
/// Default-Implementation: do nothing
|
||||||
|
virtual void activate (SceneToolbar *toolbar);
|
||||||
|
|
||||||
|
/// Default-Implementation: do nothing
|
||||||
|
virtual void deactivate (SceneToolbar *toolbar);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -72,6 +72,11 @@ CSVWidget::PushButton::PushButton (const QIcon& icon, Type type, const QString&
|
||||||
QWidget *parent)
|
QWidget *parent)
|
||||||
: QPushButton (icon, "", parent), mKeepOpen (false), mType (type), mToolTip (tooltip)
|
: QPushButton (icon, "", parent), mKeepOpen (false), mType (type), mToolTip (tooltip)
|
||||||
{
|
{
|
||||||
|
if (type==Type_Mode || type==Type_Toggle)
|
||||||
|
{
|
||||||
|
setCheckable (true);
|
||||||
|
connect (this, SIGNAL (toggled (bool)), this, SLOT (checkedStateChanged (bool)));
|
||||||
|
}
|
||||||
setCheckable (type==Type_Mode || type==Type_Toggle);
|
setCheckable (type==Type_Mode || type==Type_Toggle);
|
||||||
setExtendedToolTip();
|
setExtendedToolTip();
|
||||||
}
|
}
|
||||||
|
@ -97,3 +102,8 @@ CSVWidget::PushButton::Type CSVWidget::PushButton::getType() const
|
||||||
{
|
{
|
||||||
return mType;
|
return mType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSVWidget::PushButton::checkedStateChanged (bool checked)
|
||||||
|
{
|
||||||
|
setExtendedToolTip();
|
||||||
|
}
|
|
@ -53,6 +53,10 @@ namespace CSVWidget
|
||||||
QString getBaseToolTip() const;
|
QString getBaseToolTip() const;
|
||||||
|
|
||||||
Type getType() const;
|
Type getType() const;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
|
||||||
|
void checkedStateChanged (bool checked);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,9 +31,20 @@ CSVWidget::SceneToolbar::SceneToolbar (int buttonSize, QWidget *parent)
|
||||||
connect (focusScene, SIGNAL (activated()), this, SIGNAL (focusSceneRequest()));
|
connect (focusScene, SIGNAL (activated()), this, SIGNAL (focusSceneRequest()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVWidget::SceneToolbar::addTool (SceneTool *tool)
|
void CSVWidget::SceneToolbar::addTool (SceneTool *tool, SceneTool *insertPoint)
|
||||||
{
|
{
|
||||||
|
if (!insertPoint)
|
||||||
mLayout->addWidget (tool, 0, Qt::AlignTop);
|
mLayout->addWidget (tool, 0, Qt::AlignTop);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int index = mLayout->indexOf (insertPoint);
|
||||||
|
mLayout->insertWidget (index+1, tool, 0, Qt::AlignTop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWidget::SceneToolbar::removeTool (SceneTool *tool)
|
||||||
|
{
|
||||||
|
mLayout->removeWidget (tool);
|
||||||
}
|
}
|
||||||
|
|
||||||
int CSVWidget::SceneToolbar::getButtonSize() const
|
int CSVWidget::SceneToolbar::getButtonSize() const
|
||||||
|
|
|
@ -25,7 +25,11 @@ namespace CSVWidget
|
||||||
|
|
||||||
SceneToolbar (int buttonSize, QWidget *parent = 0);
|
SceneToolbar (int buttonSize, QWidget *parent = 0);
|
||||||
|
|
||||||
void addTool (SceneTool *tool);
|
/// If insertPoint==0, insert \a tool at the end of the scrollbar. Otherwise
|
||||||
|
/// insert tool after \a insertPoint.
|
||||||
|
void addTool (SceneTool *tool, SceneTool *insertPoint = 0);
|
||||||
|
|
||||||
|
void removeTool (SceneTool *tool);
|
||||||
|
|
||||||
int getButtonSize() const;
|
int getButtonSize() const;
|
||||||
|
|
||||||
|
|
|
@ -6,9 +6,9 @@
|
||||||
#include <QSignalMapper>
|
#include <QSignalMapper>
|
||||||
|
|
||||||
#include "scenetoolbar.hpp"
|
#include "scenetoolbar.hpp"
|
||||||
#include "pushbutton.hpp"
|
#include "modebutton.hpp"
|
||||||
|
|
||||||
void CSVWidget::SceneToolMode::adjustToolTip (const PushButton *activeMode)
|
void CSVWidget::SceneToolMode::adjustToolTip (const ModeButton *activeMode)
|
||||||
{
|
{
|
||||||
QString toolTip = mToolTip;
|
QString toolTip = mToolTip;
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ void CSVWidget::SceneToolMode::adjustToolTip (const PushButton *activeMode)
|
||||||
|
|
||||||
CSVWidget::SceneToolMode::SceneToolMode (SceneToolbar *parent, const QString& toolTip)
|
CSVWidget::SceneToolMode::SceneToolMode (SceneToolbar *parent, const QString& toolTip)
|
||||||
: SceneTool (parent), mButtonSize (parent->getButtonSize()), mIconSize (parent->getIconSize()),
|
: SceneTool (parent), mButtonSize (parent->getButtonSize()), mIconSize (parent->getIconSize()),
|
||||||
mToolTip (toolTip), mFirst (0)
|
mToolTip (toolTip), mFirst (0), mCurrent (0), mToolbar (parent)
|
||||||
{
|
{
|
||||||
mPanel = new QFrame (this, Qt::Popup);
|
mPanel = new QFrame (this, Qt::Popup);
|
||||||
|
|
||||||
|
@ -44,8 +44,14 @@ void CSVWidget::SceneToolMode::showPanel (const QPoint& position)
|
||||||
void CSVWidget::SceneToolMode::addButton (const std::string& icon, const std::string& id,
|
void CSVWidget::SceneToolMode::addButton (const std::string& icon, const std::string& id,
|
||||||
const QString& tooltip)
|
const QString& tooltip)
|
||||||
{
|
{
|
||||||
PushButton *button = new PushButton (QIcon (QPixmap (icon.c_str())), PushButton::Type_Mode,
|
ModeButton *button = new ModeButton (QIcon (QPixmap (icon.c_str())), tooltip, mPanel);
|
||||||
tooltip, mPanel);
|
addButton (button, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWidget::SceneToolMode::addButton (ModeButton *button, const std::string& id)
|
||||||
|
{
|
||||||
|
button->setParent (mPanel);
|
||||||
|
|
||||||
button->setSizePolicy (QSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed));
|
button->setSizePolicy (QSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed));
|
||||||
button->setIconSize (QSize (mIconSize, mIconSize));
|
button->setIconSize (QSize (mIconSize, mIconSize));
|
||||||
button->setFixedSize (mButtonSize, mButtonSize);
|
button->setFixedSize (mButtonSize, mButtonSize);
|
||||||
|
@ -58,29 +64,40 @@ void CSVWidget::SceneToolMode::addButton (const std::string& icon, const std::st
|
||||||
|
|
||||||
if (mButtons.size()==1)
|
if (mButtons.size()==1)
|
||||||
{
|
{
|
||||||
mFirst = button;
|
mFirst = mCurrent = button;
|
||||||
setIcon (button->icon());
|
setIcon (button->icon());
|
||||||
button->setChecked (true);
|
button->setChecked (true);
|
||||||
adjustToolTip (button);
|
adjustToolTip (button);
|
||||||
|
mCurrent->activate (mToolbar);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVWidget::SceneToolMode::selected()
|
void CSVWidget::SceneToolMode::selected()
|
||||||
{
|
{
|
||||||
std::map<PushButton *, std::string>::const_iterator iter =
|
std::map<ModeButton *, std::string>::const_iterator iter =
|
||||||
mButtons.find (dynamic_cast<PushButton *> (sender()));
|
mButtons.find (dynamic_cast<ModeButton *> (sender()));
|
||||||
|
|
||||||
if (iter!=mButtons.end())
|
if (iter!=mButtons.end())
|
||||||
{
|
{
|
||||||
if (!iter->first->hasKeepOpen())
|
if (!iter->first->hasKeepOpen())
|
||||||
mPanel->hide();
|
mPanel->hide();
|
||||||
|
|
||||||
for (std::map<PushButton *, std::string>::const_iterator iter2 = mButtons.begin();
|
for (std::map<ModeButton *, std::string>::const_iterator iter2 = mButtons.begin();
|
||||||
iter2!=mButtons.end(); ++iter2)
|
iter2!=mButtons.end(); ++iter2)
|
||||||
iter2->first->setChecked (iter2==iter);
|
iter2->first->setChecked (iter2==iter);
|
||||||
|
|
||||||
setIcon (iter->first->icon());
|
setIcon (iter->first->icon());
|
||||||
adjustToolTip (iter->first);
|
adjustToolTip (iter->first);
|
||||||
|
|
||||||
|
if (mCurrent!=iter->first)
|
||||||
|
{
|
||||||
|
if (mCurrent)
|
||||||
|
mCurrent->deactivate (mToolbar);
|
||||||
|
|
||||||
|
mCurrent = iter->first;
|
||||||
|
mCurrent->activate (mToolbar);
|
||||||
|
}
|
||||||
|
|
||||||
emit modeChanged (iter->second);
|
emit modeChanged (iter->second);
|
||||||
}
|
}
|
||||||
}
|
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue