Commit f4667d00 authored by benjamin.long's avatar benjamin.long

ENH: Internationalized Slicer

Added Internationalization setting panel to enable/disable this behavior.
Added language combo box into general setting panel if enabled.
Added function to load language when we start the application.

git-svn-id: http://svn.slicer.org/Slicer4/trunk@20514 3bd1e089-480b-0410-8dfb-8563597acbee
parent 11dd0370
......@@ -77,6 +77,27 @@ set(SlicerApp_INCLUDE_DIRECTORIES
)
include_directories(${SlicerApp_INCLUDE_DIRECTORIES})
# --------------------------------------------------------------------------
# Translation
# --------------------------------------------------------------------------
set(lib_name "qSlicerApp")
set(TS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/Resources/Translations/")
get_property(Slicer_LANGUAGES GLOBAL PROPERTY Slicer_LANGUAGES)
include(${Slicer_SOURCE_DIR}/CMake/SlicerMacroTranslation.cmake)
SlicerMacroTranslation(
SRCS ${SlicerApp_SRCS}
UI_SRCS ${SlicerApp_UI_SRCS}
TS_DIR ${TS_DIR}
TS_BASEFILENAME ${lib_name}
TS_LANGUAGES ${Slicer_LANGUAGES}
QM_OUTPUT_DIR_VAR QM_OUTPUT_DIR
QM_OUTPUT_FILES_VAR QM_OUTPUT_FILES
)
set_property(GLOBAL APPEND PROPERTY Slicer_QM_OUTPUT_DIRS ${QM_OUTPUT_DIR})
# --------------------------------------------------------------------------
# Build the library
# --------------------------------------------------------------------------
......@@ -86,6 +107,7 @@ add_library(${KIT_LIBRARY_NAME}
${SlicerApp_SRCS}
${SlicerApp_UI_CXX}
${SlicerApp_QRC_SRCS}
${QM_OUTPUT_FILES}
)
set_target_properties(${KIT_LIBRARY_NAME} PROPERTIES LABELS ${PROJECT_NAME})
......
......@@ -19,12 +19,15 @@
==============================================================================*/
// Qt includes
#include <QList>
#include <QSettings>
#include <QSplashScreen>
#include <QString>
#include <QTimer>
#include <QTranslator>
// Slicer includes
#include "vtkSlicerConfigure.h" // For Slicer_USE_PYTHONQT
#include "vtkSlicerConfigure.h" // For Slicer_USE_PYTHONQT Slicer_QM_OUTPUT_DIRS, Slicer_INSTALL_QM_DIR
// CTK includes
#include <ctkAbstractLibraryFactory.h>
......@@ -212,6 +215,56 @@ void splashMessage(QScopedPointer<QSplashScreen>& splashScreen, const QString& m
//splashScreen->repaint();
}
//----------------------------------------------------------------------------
void loadTranslations(const QString& dir)
{
qSlicerApplication * app = qSlicerApplication::application();
Q_ASSERT(app);
QString localeFilter =
QString( QString("*") + app->settings()->value("language").toString());
localeFilter.resize(3);
localeFilter += QString(".qm");
QDir directory(dir);
QStringList qmFiles = directory.entryList(QStringList(localeFilter));
foreach(QString qmFile, qmFiles)
{
QTranslator* translator = new QTranslator();
QString qmFilePath = QString(dir + QString("/") + qmFile);
if(!translator->load(qmFilePath))
{
qDebug() << "The File " << qmFile << " hasn't been loaded in the translator";
return;
}
app->installTranslator(translator);
}
}
//----------------------------------------------------------------------------
void loadLanguage()
{
qSlicerApplication * app = qSlicerApplication::application();
Q_ASSERT(app);
// we check if the application is installed or not.
if (app->isInstalled())
{
QString qmDir = QString(Slicer_QM_DIR);
loadTranslations(qmDir);
}
else
{
QStringList qmDirs = QString(Slicer_QM_OUTPUT_DIRS).split(";");
foreach(QString qmDir, qmDirs)
{
loadTranslations(qmDir);
}
}
}
//----------------------------------------------------------------------------
int SlicerAppMain(int argc, char* argv[])
{
......@@ -227,6 +280,9 @@ int SlicerAppMain(int argc, char* argv[])
return app.returnCode();
}
// We load the language selected for the application
loadLanguage();
#ifdef Slicer_USE_QtTesting
setEnableQtTesting(); // disabled the native menu bar.
#endif
......
This diff is collapsed.
This diff is collapsed.
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.0" language="fr_FR">
<context>
<name>QObject</name>
<message>
<location filename="../../qSlicerCLIProgressBar.cxx" line="107"/>
<source>Status</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../qSlicerCLIProgressBar.cxx" line="108"/>
<source>Idle</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>qSlicerCLIModuleWidget</name>
<message>
<location filename="../UI/qSlicerCLIModuleWidget.ui" line="14"/>
<source>Module</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../UI/qSlicerCLIModuleWidget.ui" line="47"/>
<source>Module Title</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../UI/qSlicerCLIModuleWidget.ui" line="59"/>
<source>vtkMRMLCommandLineModuleNode</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../UI/qSlicerCLIModuleWidget.ui" line="70"/>
<source>Parameter set:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../UI/qSlicerCLIModuleWidget.ui" line="104"/>
<source>Reset parameters to default.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../UI/qSlicerCLIModuleWidget.ui" line="107"/>
<source>Default</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../UI/qSlicerCLIModuleWidget.ui" line="130"/>
<source>Cancel the execution of the module</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../UI/qSlicerCLIModuleWidget.ui" line="133"/>
<source>Cancel</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../UI/qSlicerCLIModuleWidget.ui" line="143"/>
<source>Execute the module</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../UI/qSlicerCLIModuleWidget.ui" line="146"/>
<source>Apply</source>
<translation type="unfinished"></translation>
</message>
</context>
</TS>
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.0" language="fr_FR">
<context>
<name>QObject</name>
<message>
<location filename="../../qSlicerCoreApplication.cxx" line="563"/>
<source>Failed to create %1 directory</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>qSlicerExtensionsManagerModel</name>
<message>
<location filename="../../qSlicerExtensionsManagerModel.cxx" line="1281"/>
<source>extensionName is not specified</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../qSlicerExtensionsManagerModel.cxx" line="1285"/>
<source>slicerRevision is not specified</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../qSlicerExtensionsManagerModel.cxx" line="1289"/>
<source>slicerOs is not specified</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../qSlicerExtensionsManagerModel.cxx" line="1293"/>
<source>slicerArch is not specified</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../qSlicerExtensionsManagerModel.cxx" line="1300"/>
<source>extensionSlicerRevision [%1] is different from slicerRevision [%2]</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../qSlicerExtensionsManagerModel.cxx" line="1305"/>
<source>extensionArch [%1] is different from slicerArch [%2]</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../qSlicerExtensionsManagerModel.cxx" line="1310"/>
<source>extensionOs [%1] is different from slicerOs [%2]</source>
<translation type="unfinished"></translation>
</message>
</context>
</TS>
......@@ -74,10 +74,12 @@ set(KIT_SRCS
qSlicerSaveDataDialog.h
qSlicerSettingsCachePanel.cxx
qSlicerSettingsCachePanel.h
qSlicerSettingsModulesPanel.cxx
qSlicerSettingsModulesPanel.h
qSlicerSettingsGeneralPanel.cxx
qSlicerSettingsGeneralPanel.h
qSlicerSettingsInternationalizationPanel.cxx
qSlicerSettingsInternationalizationPanel.h
qSlicerSettingsModulesPanel.cxx
qSlicerSettingsModulesPanel.h
qSlicerStyle.cxx
qSlicerStyle.h
qSlicerViewersToolBar.cxx
......@@ -172,6 +174,7 @@ set(KIT_MOC_SRCS
qSlicerSaveDataDialog_p.h
qSlicerSettingsCachePanel.h
qSlicerSettingsGeneralPanel.h
qSlicerSettingsInternationalizationPanel.h
qSlicerSettingsModulesPanel.h
qSlicerViewersToolBar.h
qSlicerViewersToolBar_p.h
......@@ -218,6 +221,7 @@ set(KIT_UI_SRCS
Resources/UI/qSlicerSaveDataDialog.ui
Resources/UI/qSlicerSettingsCachePanel.ui
Resources/UI/qSlicerSettingsGeneralPanel.ui
Resources/UI/qSlicerSettingsInternationalizationPanel.ui
Resources/UI/qSlicerSettingsModulesPanel.ui
)
if(Slicer_BUILD_EXTENSIONMANAGER_SUPPORT)
......
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.0" language="fr_FR">
<context>
<name>QObject</name>
<message>
<location filename="../../qSlicerCoreApplication.cxx" line="563"/>
<source>Failed to create %1 directory</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>qSlicerExtensionsManagerModel</name>
<message>
<location filename="../../qSlicerExtensionsManagerModel.cxx" line="1281"/>
<source>extensionName is not specified</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../qSlicerExtensionsManagerModel.cxx" line="1285"/>
<source>slicerRevision is not specified</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../qSlicerExtensionsManagerModel.cxx" line="1289"/>
<source>slicerOs is not specified</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../qSlicerExtensionsManagerModel.cxx" line="1293"/>
<source>slicerArch is not specified</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../qSlicerExtensionsManagerModel.cxx" line="1300"/>
<source>extensionSlicerRevision [%1] is different from slicerRevision [%2]</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../qSlicerExtensionsManagerModel.cxx" line="1305"/>
<source>extensionArch [%1] is different from slicerArch [%2]</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../qSlicerExtensionsManagerModel.cxx" line="1310"/>
<source>extensionOs [%1] is different from slicerOs [%2]</source>
<translation type="unfinished"></translation>
</message>
</context>
</TS>
This diff is collapsed.
......@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>402</width>
<height>252</height>
<width>415</width>
<height>262</height>
</rect>
</property>
<property name="windowTitle">
......@@ -42,17 +42,17 @@
</property>
</widget>
</item>
<item row="4" column="0">
<item row="5" column="0">
<widget class="QLabel" name="FontLabel">
<property name="text">
<string>Font and size:</string>
</property>
</widget>
</item>
<item row="4" column="1">
<item row="5" column="1">
<widget class="ctkFontButton" name="FontButton"/>
</item>
<item row="6" column="1">
<item row="7" column="1">
<widget class="QCheckBox" name="RestoreUICheckBox">
<property name="text">
<string/>
......@@ -62,21 +62,21 @@
</property>
</widget>
</item>
<item row="6" column="0">
<item row="7" column="0">
<widget class="QLabel" name="RestoreUILabel">
<property name="text">
<string>Save user interface size and position on exit:</string>
</property>
</widget>
</item>
<item row="8" column="0">
<item row="9" column="0">
<widget class="QLabel" name="ConfirmExitLabel">
<property name="text">
<string>Confirm on exit:</string>
</property>
</widget>
</item>
<item row="8" column="1">
<item row="9" column="1">
<widget class="QCheckBox" name="ConfirmExitCheckBox">
<property name="text">
<string/>
......@@ -86,28 +86,28 @@
</property>
</widget>
</item>
<item row="5" column="0">
<item row="6" column="0">
<widget class="QLabel" name="ShowToolButtonTextLabel">
<property name="text">
<string>Show text under icons in toolbar buttons:</string>
</property>
</widget>
</item>
<item row="5" column="1">
<item row="6" column="1">
<widget class="QCheckBox" name="ShowToolButtonTextCheckBox">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="7" column="0">
<item row="8" column="0">
<widget class="QLabel" name="ConfirmRestartLabel">
<property name="text">
<string>Confirm on restart:</string>
</property>
</widget>
</item>
<item row="7" column="1">
<item row="8" column="1">
<widget class="QCheckBox" name="ConfirmRestartCheckBox">
<property name="text">
<string/>
......@@ -117,19 +117,34 @@
</property>
</widget>
</item>
<item row="9" column="0">
<item row="10" column="0">
<widget class="QLabel" name="SlicerWikiURLLabel">
<property name="text">
<string>Slicer Wiki URL:</string>
</property>
</widget>
</item>
<item row="9" column="1">
<item row="10" column="1">
<widget class="QLineEdit" name="SlicerWikiURLLineEdit"/>
</item>
<item row="4" column="1">
<widget class="ctkLanguageComboBox" name="LanguageComboBox"/>
</item>
<item row="4" column="0">
<widget class="QLabel" name="LanguageLabel">
<property name="text">
<string>Language</string>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>ctkFontButton</class>
<extends>QPushButton</extends>
<header>ctkFontButton.h</header>
</customwidget>
<customwidget>
<class>ctkSettingsPanel</class>
<extends>QWidget</extends>
......@@ -137,9 +152,9 @@
<container>1</container>
</customwidget>
<customwidget>
<class>ctkFontButton</class>
<extends>QPushButton</extends>
<header>ctkFontButton.h</header>
<class>ctkLanguageComboBox</class>
<extends>QComboBox</extends>
<header>ctkLanguageComboBox.h</header>
</customwidget>
</customwidgets>
<resources/>
......
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>qSlicerSettingsInternationalizationPanel</class>
<widget class="ctkSettingsPanel" name="qSlicerSettingsInternationalizationPanel">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>751</width>
<height>128</height>
</rect>
</property>
<property name="windowTitle">
<string>Internationalization</string>
</property>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="InternationalizationEnabledLabel">
<property name="text">
<string>Enable Internationalization:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="InternationalizationEnabledCheckBox">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>ctkSettingsPanel</class>
<extends>QWidget</extends>
<header>ctkSettingsPanel.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
......@@ -54,6 +54,7 @@
#endif
#include "qSlicerSettingsCachePanel.h"
#include "qSlicerSettingsGeneralPanel.h"
#include "qSlicerSettingsInternationalizationPanel.h"
#ifdef Slicer_USE_QtTesting
# include "qSlicerSettingsQtTestingPanel.h"
#endif
......@@ -184,6 +185,10 @@ void qSlicerApplicationPrivate::init()
cachePanel->setCacheManager(this->MRMLScene->GetCacheManager());
this->SettingsDialog->addPanel("Cache", cachePanel);
qSlicerSettingsInternationalizationPanel* qtInternationalizationPanel =
new qSlicerSettingsInternationalizationPanel;
this->SettingsDialog->addPanel("Internationalization", qtInternationalizationPanel);
#ifdef Slicer_USE_QtTesting
qSlicerSettingsQtTestingPanel* qtTestingPanel = new qSlicerSettingsQtTestingPanel;
this->SettingsDialog->addPanel("QtTesting", qtTestingPanel);
......
......@@ -32,6 +32,8 @@
#include "qSlicerSettingsGeneralPanel.h"
#include "ui_qSlicerSettingsGeneralPanel.h"
#include "vtkSlicerConfigure.h" // For Slicer_QM_OUTPUT_DIRS
// --------------------------------------------------------------------------
// qSlicerSettingsGeneralPanelPrivate
......@@ -63,6 +65,17 @@ void qSlicerSettingsGeneralPanelPrivate::init()
Q_Q(qSlicerSettingsGeneralPanel);
this->setupUi(q);
bool internationalizationEnabled =
qSlicerApplication::application()->settings()->value("Internationalization/Enabled").toBool();
this->LanguageLabel->setVisible(internationalizationEnabled);
this->LanguageComboBox->setVisible(internationalizationEnabled);
/// Default values
this->LanguageComboBox->setDefaultLanguage("en");
/// set the directory where all the translations files are.
this->LanguageComboBox->setDirectory(
QString(Slicer_QM_OUTPUT_DIRS).split(";").at(0));
QObject::connect(this->FontButton, SIGNAL(currentFontChanged(QFont)),
q, SLOT(onFontChanged(QFont)));
QObject::connect(this->ShowToolTipsCheckBox, SIGNAL(toggled(bool)),
......@@ -95,6 +108,10 @@ void qSlicerSettingsGeneralPanelPrivate::init()
exitMapper, "valueAsInt", SIGNAL(valueAsIntChanged(int)));
q->registerProperty("SlicerWikiURL", this->SlicerWikiURLLineEdit, "text",
SIGNAL(textChanged(QString)));
q->registerProperty("language", this->LanguageComboBox, "currentLanguage",
SIGNAL(currentLanguageNameChanged(const QString&)),
"Enable/Disable languages",
ctkSettingsPanel::OptionRequireRestart);
}
// --------------------------------------------------------------------------
......
/*==============================================================================
Program: 3D Slicer
Copyright (c) Kitware Inc.
See COPYRIGHT.txt
or http://www.slicer.org/copyright/copyright.txt for details.
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file was originally developed by Benjamin Long, Kitware Inc.
and was partially funded by NIH grant 3P41RR013218-12S1
==============================================================================*/
// Qt includes
#include <QSettings>
// QtGUI includes
#include "qSlicerApplication.h"
#include "qSlicerSettingsInternationalizationPanel.h"
#include "ui_qSlicerSettingsInternationalizationPanel.h"
// --------------------------------------------------------------------------
// qSlicerSettingsInternationalizationPanelPrivate
//-----------------------------------------------------------------------------
class qSlicerSettingsInternationalizationPanelPrivate: public Ui_qSlicerSettingsInternationalizationPanel
{
Q_DECLARE_PUBLIC(qSlicerSettingsInternationalizationPanel);
protected:
qSlicerSettingsInternationalizationPanel* const q_ptr;
public:
qSlicerSettingsInternationalizationPanelPrivate(qSlicerSettingsInternationalizationPanel& object);
void init();
};
// --------------------------------------------------------------------------
// qSlicerSettingsInternationalizationPanelPrivate methods
// --------------------------------------------------------------------------
qSlicerSettingsInternationalizationPanelPrivate
::qSlicerSettingsInternationalizationPanelPrivate(qSlicerSettingsInternationalizationPanel& object)
:q_ptr(&object)
{
}
// --------------------------------------------------------------------------
void qSlicerSettingsInternationalizationPanelPrivate::init()
{
Q_Q(qSlicerSettingsInternationalizationPanel);
this->setupUi(q);
// Default values
this->InternationalizationEnabledCheckBox->setChecked(false);
// Register settings
q->registerProperty("Internationalization/Enabled",
this->InternationalizationEnabledCheckBox,
"checked", SIGNAL(toggled(bool)),
"Enable/Disable Internationalization",
ctkSettingsPanel::OptionRequireRestart);
// Actions to propagate to the application when settings are changed
QObject::connect(this->InternationalizationEnabledCheckBox, SIGNAL(toggled(bool)),
q, SLOT(enableInternationalization(bool)));
}
// --------------------------------------------------------------------------
// qSlicerSettingsInternationalizationPanel methods
// --------------------------------------------------------------------------
qSlicerSettingsInternationalizationPanel::qSlicerSettingsInternationalizationPanel(QWidget* _parent)
: Superclass(_parent)
, d_ptr(new qSlicerSettingsInternationalizationPanelPrivate(*this))
{
Q_D(qSlicerSettingsInternationalizationPanel);
d->init();
}
// --------------------------------------------------------------------------
qSlicerSettingsInternationalizationPanel::~qSlicerSettingsInternationalizationPanel()
{
}
// --------------------------------------------------------------------------
void qSlicerSettingsInternationalizationPanel::enableInternationalization(bool value)
{
Q_UNUSED(value);
}
/*==============================================================================
Program: 3D Slicer
Copyright (c) Kitware Inc.
See COPYRIGHT.txt
or http://www.slicer.org/copyright/copyright.txt for details.
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This file was originally developed by Benjamin Long, Kitware Inc.
and was partially funded by NIH grant 3P41RR013218-12S1
==============================================================================*/
#ifndef __qSlicerSettingsInternationalizationPanel_h
#define __qSlicerSettingsInternationalizationPanel_h
// Qt includes
#include <QWidget>
// CTK includes
#include <ctkSettingsPanel.h>
// QtGUI includes
#include "qSlicerBaseQTGUIExport.h"
class QSettings;
class qSlicerSettingsInternationalizationPanelPrivate;
class Q_SLICER_BASE_QTGUI_EXPORT qSlicerSettingsInternationalizationPanel
: public ctkSettingsPanel