|
|
|
@ -19,7 +19,6 @@
|
|
|
|
|
|
|
|
|
|
#include "utils/textinputdialog.hpp"
|
|
|
|
|
#include "components/contentselector/view/contentselector.hpp"
|
|
|
|
|
#include "components/contentselector/model/contentmodel.hpp"
|
|
|
|
|
|
|
|
|
|
#include <QDebug>
|
|
|
|
|
|
|
|
|
@ -28,176 +27,59 @@ DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, GameSettings &gam
|
|
|
|
|
, mGameSettings(gameSettings)
|
|
|
|
|
, mLauncherSettings(launcherSettings)
|
|
|
|
|
{
|
|
|
|
|
setupUi(this);
|
|
|
|
|
/*
|
|
|
|
|
// QMetaObject::connectSlotsByName(this);
|
|
|
|
|
unsigned char flags;
|
|
|
|
|
|
|
|
|
|
projectGroupBox->hide();
|
|
|
|
|
flags = ContentSelectorView::Flag_Content | ContentSelectorView::Flag_Profile;
|
|
|
|
|
|
|
|
|
|
// Create a dialog for the new profile name input
|
|
|
|
|
mNewProfileDialog = new TextInputDialog(tr("New Profile"), tr("Profile name:"), this);
|
|
|
|
|
ContentSelectorView::ContentSelector::configure(this, flags);
|
|
|
|
|
|
|
|
|
|
connect(mNewProfileDialog->lineEdit(), SIGNAL(textChanged(QString)), this, SLOT(updateOkButton(QString)));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
buildContentModel();
|
|
|
|
|
buildGameFileView();
|
|
|
|
|
buildAddonView();
|
|
|
|
|
buildProfilesView();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
createActions();
|
|
|
|
|
setupDataFiles();
|
|
|
|
|
|
|
|
|
|
ContentSelectorView::ContentSelector &cSelector =
|
|
|
|
|
ContentSelectorView::ContentSelector::instance();
|
|
|
|
|
|
|
|
|
|
updateViews();*/
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DataFilesPage::buildContentModel()
|
|
|
|
|
{
|
|
|
|
|
mContentModel = new ContentSelectorModel::ContentModel();
|
|
|
|
|
connect(mContentModel, SIGNAL(layoutChanged()), this, SLOT(updateViews()));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DataFilesPage::buildGameFileView()
|
|
|
|
|
{
|
|
|
|
|
mGameFileProxyModel = new QSortFilterProxyModel(this);
|
|
|
|
|
mGameFileProxyModel->setFilterRegExp(QString::number((int)ContentSelectorModel::ContentType_GameFile));
|
|
|
|
|
mGameFileProxyModel->setFilterRole (Qt::UserRole);
|
|
|
|
|
mGameFileProxyModel->setSourceModel (mContentModel);
|
|
|
|
|
|
|
|
|
|
gameFileView->setPlaceholderText(QString("Select a game file..."));
|
|
|
|
|
gameFileView->setModel(mGameFileProxyModel);
|
|
|
|
|
|
|
|
|
|
connect(gameFileView, SIGNAL(currentIndexChanged(int)), this, SLOT(slotCurrentGameFileIndexChanged(int)));
|
|
|
|
|
|
|
|
|
|
gameFileView->setCurrentIndex(-1);
|
|
|
|
|
gameFileView->setCurrentIndex(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DataFilesPage::buildAddonView()
|
|
|
|
|
{
|
|
|
|
|
mAddonProxyModel = new QSortFilterProxyModel(this);
|
|
|
|
|
mAddonProxyModel->setFilterRegExp (QString::number((int)ContentSelectorModel::ContentType_Addon));
|
|
|
|
|
mAddonProxyModel->setFilterRole (Qt::UserRole);
|
|
|
|
|
mAddonProxyModel->setDynamicSortFilter (true);
|
|
|
|
|
mAddonProxyModel->setSourceModel (mContentModel);
|
|
|
|
|
|
|
|
|
|
addonView->setModel(mAddonProxyModel);
|
|
|
|
|
connect (&cSelector, SIGNAL (signalProfileRenamed (QString, QString)),
|
|
|
|
|
this, SLOT (slotProfileRenamed (QString, QString)));
|
|
|
|
|
|
|
|
|
|
connect(addonView, SIGNAL(clicked(const QModelIndex &)), this, SLOT(slotAddonTableItemClicked(const QModelIndex &)));
|
|
|
|
|
}
|
|
|
|
|
connect (&cSelector, SIGNAL (signalProfileChanged (QString, QString)),
|
|
|
|
|
this, SLOT (slotProfileChanged (QString, QString)));
|
|
|
|
|
|
|
|
|
|
void DataFilesPage::buildProfilesView()
|
|
|
|
|
{
|
|
|
|
|
profilesComboBox->setPlaceholderText(QString("Select a profile..."));
|
|
|
|
|
connect(profilesComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(slotCurrentProfileIndexChanged(int)));
|
|
|
|
|
}
|
|
|
|
|
connect (&cSelector, SIGNAL (signalProfileDeleted (QString)),
|
|
|
|
|
this, SLOT (slotProfileDeleted (QString)));
|
|
|
|
|
|
|
|
|
|
void DataFilesPage::updateViews()
|
|
|
|
|
{
|
|
|
|
|
// Ensure the columns are hidden because sort() re-enables them
|
|
|
|
|
addonView->setColumnHidden(1, true);
|
|
|
|
|
addonView->setColumnHidden(2, true);
|
|
|
|
|
addonView->setColumnHidden(3, true);
|
|
|
|
|
addonView->setColumnHidden(4, true);
|
|
|
|
|
addonView->setColumnHidden(5, true);
|
|
|
|
|
addonView->setColumnHidden(6, true);
|
|
|
|
|
addonView->setColumnHidden(7, true);
|
|
|
|
|
addonView->setColumnHidden(8, true);
|
|
|
|
|
addonView->resizeColumnsToContents();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ContentSelectorView::ContentSelector::addFiles(const QString &path)
|
|
|
|
|
{
|
|
|
|
|
// mContentModel->addFiles(path);
|
|
|
|
|
//mContentModel->sort(3); // Sort by date accessed
|
|
|
|
|
// ui.gameFileView->setCurrentIndex(-1);
|
|
|
|
|
// mContentModel->uncheckAll();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DataFilesPage::createActions()
|
|
|
|
|
{
|
|
|
|
|
// Add the actions to the toolbuttons
|
|
|
|
|
newProfileButton->setDefaultAction(newProfileAction);
|
|
|
|
|
deleteProfileButton->setDefaultAction(deleteProfileAction);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DataFilesPage::setupDataFiles()
|
|
|
|
|
{
|
|
|
|
|
// Set the encoding to the one found in openmw.cfg or the default
|
|
|
|
|
//mContentSelector.setEncoding(mGameSettings.value(QString("encoding"), QString("win1252")));
|
|
|
|
|
|
|
|
|
|
QStringList paths = mGameSettings.getDataDirs();
|
|
|
|
|
|
|
|
|
|
foreach (const QString &path, paths) {
|
|
|
|
|
//mContentSelector.
|
|
|
|
|
mContentModel->addFiles(path);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString dataLocal = mGameSettings.getDataLocal();
|
|
|
|
|
if (!dataLocal.isEmpty())
|
|
|
|
|
//mContentSelector.
|
|
|
|
|
mContentModel->addFiles(dataLocal);
|
|
|
|
|
|
|
|
|
|
// Sort by date accessed for now
|
|
|
|
|
//mContentSelector->sort(3);
|
|
|
|
|
|
|
|
|
|
QStringList profiles = mLauncherSettings.subKeys(QString("Profiles/"));
|
|
|
|
|
QString profile = mLauncherSettings.value(QString("Profiles/currentprofile"));
|
|
|
|
|
|
|
|
|
|
if (!profiles.isEmpty())
|
|
|
|
|
profilesComboBox->addItems(profiles);
|
|
|
|
|
|
|
|
|
|
// Add the current profile if empty
|
|
|
|
|
if (profilesComboBox->findText(profile) == -1 && !profile.isEmpty())
|
|
|
|
|
profilesComboBox->addItem(profile);
|
|
|
|
|
|
|
|
|
|
if (profilesComboBox->findText(QString("Default")) == -1)
|
|
|
|
|
profilesComboBox->addItem(QString("Default"));
|
|
|
|
|
|
|
|
|
|
if (profile.isEmpty() || profile == QLatin1String("Default")) {
|
|
|
|
|
deleteProfileAction->setEnabled(false);
|
|
|
|
|
profilesComboBox->setEditEnabled(false);
|
|
|
|
|
profilesComboBox->setCurrentIndex(profilesComboBox->findText(QString("Default")));
|
|
|
|
|
} else {
|
|
|
|
|
profilesComboBox->setEditEnabled(true);
|
|
|
|
|
profilesComboBox->setCurrentIndex(profilesComboBox->findText(profile));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// We do this here to prevent deletion of profiles when initializing the combobox
|
|
|
|
|
connect(profilesComboBox, SIGNAL(profileRenamed(QString,QString)), this, SLOT(profileRenamed(QString,QString)));
|
|
|
|
|
connect(profilesComboBox, SIGNAL(profileChanged(QString,QString)), this, SLOT(profileChanged(QString,QString)));
|
|
|
|
|
|
|
|
|
|
loadSettings();
|
|
|
|
|
|
|
|
|
|
gameFileView->setCurrentIndex(-1);
|
|
|
|
|
connect (&cSelector, SIGNAL (signalProfileAdded ()),
|
|
|
|
|
this, SLOT (slotProfileAdded ()));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DataFilesPage::loadSettings()
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
QString profile = mLauncherSettings.value(QString("Profiles/currentprofile"));
|
|
|
|
|
|
|
|
|
|
if (profile.isEmpty())
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
// mContentSelector.
|
|
|
|
|
mContentModel->uncheckAll();
|
|
|
|
|
|
|
|
|
|
QStringList gameFiles = mLauncherSettings.values(QString("Profiles/") + profile + QString("/master"), Qt::MatchExactly);
|
|
|
|
|
QStringList files = mLauncherSettings.values(QString("Profiles/") + profile + QString("/master"), Qt::MatchExactly);
|
|
|
|
|
QStringList addons = mLauncherSettings.values(QString("Profiles/") + profile + QString("/plugin"), Qt::MatchExactly);
|
|
|
|
|
|
|
|
|
|
foreach (const QString &file, addons)
|
|
|
|
|
files.append(file);
|
|
|
|
|
|
|
|
|
|
//ContentSelectorView::ContentSelector::instance().setCheckStates(files);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DataFilesPage::saveSettings()
|
|
|
|
|
{
|
|
|
|
|
if (mContentModel->rowCount() < 1)
|
|
|
|
|
return;
|
|
|
|
|
ContentSelectorModel::ContentFileList items =
|
|
|
|
|
ContentSelectorView::ContentSelector::instance().selectedFiles();
|
|
|
|
|
|
|
|
|
|
if (items.size() == 0)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
QString profile = mLauncherSettings.value(QString("Profiles/currentprofile"));
|
|
|
|
|
|
|
|
|
|
if (profile.isEmpty()) {
|
|
|
|
|
profile = profilesComboBox->currentText();
|
|
|
|
|
profile = ContentSelectorView::ContentSelector::instance().getProfileText();
|
|
|
|
|
mLauncherSettings.setValue(QString("Profiles/currentprofile"), profile);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -207,8 +89,6 @@ void DataFilesPage::saveSettings()
|
|
|
|
|
mGameSettings.remove(QString("master"));
|
|
|
|
|
mGameSettings.remove(QString("plugin"));
|
|
|
|
|
|
|
|
|
|
ContentSelectorModel::ContentFileList items = mContentModel->checkedItems();
|
|
|
|
|
|
|
|
|
|
foreach(const ContentSelectorModel::EsmFile *item, items) {
|
|
|
|
|
|
|
|
|
|
if (item->gameFiles().size() == 0) {
|
|
|
|
@ -223,109 +103,18 @@ void DataFilesPage::saveSettings()
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DataFilesPage::updateOkButton(const QString &text)
|
|
|
|
|
void DataFilesPage::slotProfileDeleted (const QString &item)
|
|
|
|
|
{
|
|
|
|
|
// We do this here because we need the profiles combobox text
|
|
|
|
|
if (text.isEmpty()) {
|
|
|
|
|
mNewProfileDialog->setOkButtonEnabled(false);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
(profilesComboBox->findText(text) == -1)
|
|
|
|
|
? mNewProfileDialog->setOkButtonEnabled(true)
|
|
|
|
|
: mNewProfileDialog->setOkButtonEnabled(false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DataFilesPage::setProfilesComboBoxIndex(int index)
|
|
|
|
|
{
|
|
|
|
|
profilesComboBox->setCurrentIndex(index);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QAbstractItemModel* DataFilesPage::profilesComboBoxModel()
|
|
|
|
|
{
|
|
|
|
|
return profilesComboBox->model();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int DataFilesPage::profilesComboBoxIndex()
|
|
|
|
|
{
|
|
|
|
|
return profilesComboBox->currentIndex();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DataFilesPage::on_newProfileAction_triggered()
|
|
|
|
|
{
|
|
|
|
|
if (mNewProfileDialog->exec() == QDialog::Accepted) {
|
|
|
|
|
QString profile = mNewProfileDialog->lineEdit()->text();
|
|
|
|
|
profilesComboBox->addItem(profile);
|
|
|
|
|
profilesComboBox->setCurrentIndex(profilesComboBox->findText(profile));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DataFilesPage::on_deleteProfileAction_triggered()
|
|
|
|
|
{
|
|
|
|
|
QString profile = profilesComboBox->currentText();
|
|
|
|
|
|
|
|
|
|
if (profile.isEmpty())
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
QMessageBox msgBox(this);
|
|
|
|
|
msgBox.setWindowTitle(tr("Delete Profile"));
|
|
|
|
|
msgBox.setIcon(QMessageBox::Warning);
|
|
|
|
|
msgBox.setStandardButtons(QMessageBox::Cancel);
|
|
|
|
|
msgBox.setText(tr("Are you sure you want to delete <b>%0</b>?").arg(profile));
|
|
|
|
|
|
|
|
|
|
QAbstractButton *deleteButton =
|
|
|
|
|
msgBox.addButton(tr("Delete"), QMessageBox::ActionRole);
|
|
|
|
|
|
|
|
|
|
msgBox.exec();
|
|
|
|
|
|
|
|
|
|
if (msgBox.clickedButton() == deleteButton) {
|
|
|
|
|
mLauncherSettings.remove(QString("Profiles/") + profile + QString("/master"));
|
|
|
|
|
mLauncherSettings.remove(QString("Profiles/") + profile + QString("/plugin"));
|
|
|
|
|
|
|
|
|
|
// Remove the profile from the combobox
|
|
|
|
|
profilesComboBox->removeItem(profilesComboBox->findText(profile));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DataFilesPage::setPluginsCheckstates(Qt::CheckState state)
|
|
|
|
|
{
|
|
|
|
|
if (!addonView->selectionModel()->hasSelection()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QModelIndexList indexes = addonView->selectionModel()->selectedIndexes();
|
|
|
|
|
|
|
|
|
|
foreach (const QModelIndex &index, indexes)
|
|
|
|
|
{
|
|
|
|
|
if (!index.isValid())
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
QModelIndex sourceIndex = mAddonProxyModel->mapToSource(index);
|
|
|
|
|
|
|
|
|
|
if (!sourceIndex.isValid())
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
//bool isChecked = ( state == Qt::Checked );
|
|
|
|
|
|
|
|
|
|
mContentModel->setData(sourceIndex, state, Qt::CheckStateRole);
|
|
|
|
|
}
|
|
|
|
|
mLauncherSettings.remove(QString("Profiles/") + item + QString("/master"));
|
|
|
|
|
mLauncherSettings.remove(QString("Profiles/") + item + QString("/plugin"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DataFilesPage::profileChanged(const QString &previous, const QString ¤t)
|
|
|
|
|
void DataFilesPage::slotProfileChanged(const QString &previous, const QString ¤t)
|
|
|
|
|
{
|
|
|
|
|
// Prevent the deletion of the default profile
|
|
|
|
|
if (current == QLatin1String("Default")) {
|
|
|
|
|
deleteProfileAction->setEnabled(false);
|
|
|
|
|
profilesComboBox->setEditEnabled(false);
|
|
|
|
|
} else {
|
|
|
|
|
deleteProfileAction->setEnabled(true);
|
|
|
|
|
profilesComboBox->setEditEnabled(true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (previous.isEmpty())
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (profilesComboBox->findText(previous) == -1)
|
|
|
|
|
if (ContentSelectorView::ContentSelector::instance().getProfileIndex (previous) == -1)
|
|
|
|
|
return; // Profile was deleted
|
|
|
|
|
|
|
|
|
|
// Store the previous profile
|
|
|
|
@ -336,7 +125,7 @@ void DataFilesPage::profileChanged(const QString &previous, const QString &curre
|
|
|
|
|
loadSettings();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DataFilesPage::profileRenamed(const QString &previous, const QString ¤t)
|
|
|
|
|
void DataFilesPage::slotProfileRenamed(const QString &previous, const QString ¤t)
|
|
|
|
|
{
|
|
|
|
|
if (previous.isEmpty())
|
|
|
|
|
return;
|
|
|
|
@ -350,56 +139,55 @@ void DataFilesPage::profileRenamed(const QString &previous, const QString &curre
|
|
|
|
|
mLauncherSettings.remove(QString("Profiles/") + previous + QString("/plugin"));
|
|
|
|
|
|
|
|
|
|
// Remove the profile from the combobox
|
|
|
|
|
profilesComboBox->removeItem(profilesComboBox->findText(previous));
|
|
|
|
|
ContentSelectorView::ContentSelector::instance().removeProfile (previous);
|
|
|
|
|
|
|
|
|
|
loadSettings();
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////
|
|
|
|
|
|
|
|
|
|
QStringList DataFilesPage::checkedItemsPaths()
|
|
|
|
|
void DataFilesPage::slotProfileAdded()
|
|
|
|
|
{
|
|
|
|
|
QStringList itemPaths;
|
|
|
|
|
TextInputDialog newDialog (tr("New Profile"), tr("Profile name:"), this);
|
|
|
|
|
|
|
|
|
|
foreach( const ContentSelectorModel::EsmFile *file, mContentModel->checkedItems())
|
|
|
|
|
itemPaths << file->path();
|
|
|
|
|
// connect(mNewDialog->lineEdit(), SIGNAL(textChanged(QString)),
|
|
|
|
|
// this, SLOT(updateOkButton(QString)));
|
|
|
|
|
|
|
|
|
|
return itemPaths;
|
|
|
|
|
if (newDialog.exec() == QDialog::Accepted)
|
|
|
|
|
{
|
|
|
|
|
QString profile = newDialog.lineEdit()->text();
|
|
|
|
|
|
|
|
|
|
ContentSelectorView::ContentSelector
|
|
|
|
|
::instance().addProfile(profile, true);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DataFilesPage::slotCurrentProfileIndexChanged(int index)
|
|
|
|
|
void DataFilesPage::setProfilesComboBoxIndex(int index)
|
|
|
|
|
{
|
|
|
|
|
emit profileChanged(index);
|
|
|
|
|
ContentSelectorView::ContentSelector::instance().setProfileIndex(index);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DataFilesPage::slotCurrentGameFileIndexChanged(int index)
|
|
|
|
|
void DataFilesPage::setupDataFiles()
|
|
|
|
|
{
|
|
|
|
|
static int oldIndex = -1;
|
|
|
|
|
ContentSelectorView::ContentSelector &cSelector =
|
|
|
|
|
ContentSelectorView::ContentSelector::instance();
|
|
|
|
|
|
|
|
|
|
QStringList paths = mGameSettings.getDataDirs();
|
|
|
|
|
|
|
|
|
|
QAbstractItemModel *const model = gameFileView->model();
|
|
|
|
|
QSortFilterProxyModel *proxy = dynamic_cast<QSortFilterProxyModel *>(model);
|
|
|
|
|
foreach (const QString &path, paths)
|
|
|
|
|
cSelector.addFiles(path);
|
|
|
|
|
|
|
|
|
|
if (proxy)
|
|
|
|
|
proxy->setDynamicSortFilter(false);
|
|
|
|
|
QString dataLocal = mGameSettings.getDataLocal();
|
|
|
|
|
|
|
|
|
|
if (oldIndex > -1)
|
|
|
|
|
model->setData(model->index(oldIndex, 0), false, Qt::UserRole + 1);
|
|
|
|
|
if (!dataLocal.isEmpty())
|
|
|
|
|
cSelector.addFiles(dataLocal);
|
|
|
|
|
|
|
|
|
|
oldIndex = index;
|
|
|
|
|
QStringList profiles = mLauncherSettings.subKeys(QString("Profiles/"));
|
|
|
|
|
QString profile = mLauncherSettings.value(QString("Profiles/currentprofile"));
|
|
|
|
|
|
|
|
|
|
model->setData(model->index(index, 0), true, Qt::UserRole + 1);
|
|
|
|
|
|
|
|
|
|
if (proxy)
|
|
|
|
|
proxy->setDynamicSortFilter(true);
|
|
|
|
|
}
|
|
|
|
|
foreach (const QString &item, profiles)
|
|
|
|
|
cSelector.addProfile (item);
|
|
|
|
|
|
|
|
|
|
void DataFilesPage::slotAddonTableItemClicked(const QModelIndex &index)
|
|
|
|
|
{
|
|
|
|
|
QAbstractItemModel *const model = addonView->model();
|
|
|
|
|
//QSortFilterProxyModel *proxy = dynamic_cast<QSortFilterProxyModel *>(model);
|
|
|
|
|
cSelector.addProfile (profile, true);
|
|
|
|
|
|
|
|
|
|
if (model->data(index, Qt::CheckStateRole).toInt() == Qt::Unchecked)
|
|
|
|
|
model->setData(index, Qt::Checked, Qt::CheckStateRole);
|
|
|
|
|
else
|
|
|
|
|
model->setData(index, Qt::Unchecked, Qt::CheckStateRole);
|
|
|
|
|
loadSettings();
|
|
|
|
|
}
|
|
|
|
|