File indexing completed on 2024-04-28 17:03:14
0001 /* 0002 * SPDX-FileCopyrightText: 2006 Peter Penz <peter.penz@gmx.at> 0003 * SPDX-FileCopyrightText: 2018 Elvis Angelaccio <elvis.angelaccio@kde.org> 0004 * 0005 * SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 #include "viewpropertiesdialog.h" 0009 0010 #include "dolphin_generalsettings.h" 0011 #include "global.h" 0012 #include "kitemviews/kfileitemmodel.h" 0013 #include "viewpropsprogressinfo.h" 0014 #include "views/dolphinview.h" 0015 0016 #include <KCollapsibleGroupBox> 0017 #include <KLocalizedString> 0018 #include <KMessageBox> 0019 #include <KWindowConfig> 0020 0021 #include <kwidgetsaddons_version.h> 0022 0023 #if HAVE_BALOO 0024 #include <Baloo/IndexerConfig> 0025 #endif 0026 0027 #include <QButtonGroup> 0028 #include <QCheckBox> 0029 #include <QComboBox> 0030 #include <QFormLayout> 0031 #include <QLabel> 0032 #include <QListWidget> 0033 #include <QPushButton> 0034 #include <QRadioButton> 0035 #include <QSpacerItem> 0036 0037 #include <views/viewproperties.h> 0038 0039 ViewPropertiesDialog::ViewPropertiesDialog(DolphinView *dolphinView) 0040 : QDialog(dolphinView) 0041 , m_isDirty(false) 0042 , m_dolphinView(dolphinView) 0043 , m_viewProps(nullptr) 0044 , m_viewMode(nullptr) 0045 , m_sortOrder(nullptr) 0046 , m_sorting(nullptr) 0047 , m_sortFoldersFirst(nullptr) 0048 , m_sortHiddenLast(nullptr) 0049 , m_previewsShown(nullptr) 0050 , m_showInGroups(nullptr) 0051 , m_showHiddenFiles(nullptr) 0052 , m_applyToCurrentFolder(nullptr) 0053 , m_applyToSubFolders(nullptr) 0054 , m_applyToAllFolders(nullptr) 0055 , m_useAsDefault(nullptr) 0056 { 0057 Q_ASSERT(dolphinView); 0058 const bool useGlobalViewProps = GeneralSettings::globalViewProps(); 0059 0060 setWindowTitle(i18nc("@title:window", "View Display Style")); 0061 0062 const QUrl &url = dolphinView->url(); 0063 m_viewProps = new ViewProperties(url); 0064 m_viewProps->setAutoSaveEnabled(false); 0065 0066 auto layout = new QFormLayout(this); 0067 // Otherwise the dialog won't resize when we collapse the KCollapsibleGroupBox. 0068 layout->setSizeConstraint(QLayout::SetFixedSize); 0069 0070 // create 'Properties' group containing view mode, sorting, sort order and show hidden files 0071 m_viewMode = new QComboBox(); 0072 m_viewMode->addItem(QIcon::fromTheme(QStringLiteral("view-list-icons")), i18nc("@item:inlistbox", "Icons"), DolphinView::IconsView); 0073 m_viewMode->addItem(QIcon::fromTheme(QStringLiteral("view-list-details")), i18nc("@item:inlistbox", "Compact"), DolphinView::CompactView); 0074 m_viewMode->addItem(QIcon::fromTheme(QStringLiteral("view-list-tree")), i18nc("@item:inlistbox", "Details"), DolphinView::DetailsView); 0075 0076 m_sortOrder = new QComboBox(); 0077 m_sortOrder->addItem(i18nc("@item:inlistbox Sort", "Ascending")); 0078 m_sortOrder->addItem(i18nc("@item:inlistbox Sort", "Descending")); 0079 0080 m_sorting = new QComboBox(); 0081 const QList<KFileItemModel::RoleInfo> rolesInfo = KFileItemModel::rolesInformation(); 0082 for (const KFileItemModel::RoleInfo &info : rolesInfo) { 0083 m_sorting->addItem(info.translation, info.role); 0084 } 0085 0086 m_sortFoldersFirst = new QCheckBox(i18nc("@option:check", "Show folders first")); 0087 m_sortHiddenLast = new QCheckBox(i18nc("@option:check", "Show hidden files last")); 0088 m_previewsShown = new QCheckBox(i18nc("@option:check", "Show preview")); 0089 m_showInGroups = new QCheckBox(i18nc("@option:check", "Show in groups")); 0090 m_showHiddenFiles = new QCheckBox(i18nc("@option:check", "Show hidden files")); 0091 0092 auto additionalInfoBox = new KCollapsibleGroupBox(); 0093 additionalInfoBox->setTitle(i18nc("@title:group", "Additional Information")); 0094 auto innerLayout = new QVBoxLayout(additionalInfoBox); 0095 0096 { 0097 QList<QByteArray> visibleRoles = m_viewProps->visibleRoles(); 0098 const bool useDefaultRoles = (m_viewProps->viewMode() == DolphinView::DetailsView) && visibleRoles.isEmpty(); 0099 if (useDefaultRoles) { 0100 // Using the details view without any additional information (-> additional column) 0101 // makes no sense and leads to a usability problem as no viewport area is available 0102 // anymore. Hence as fallback provide at least a size and date column. 0103 visibleRoles.clear(); 0104 visibleRoles.append("text"); 0105 visibleRoles.append("size"); 0106 visibleRoles.append("modificationtime"); 0107 m_viewProps->setVisibleRoles(visibleRoles); 0108 } 0109 0110 // Add checkboxes 0111 bool indexingEnabled = false; 0112 #if HAVE_BALOO 0113 Baloo::IndexerConfig config; 0114 indexingEnabled = config.fileIndexingEnabled(); 0115 #endif 0116 0117 m_listWidget = new QListWidget(); 0118 connect(m_listWidget, &QListWidget::itemChanged, this, &ViewPropertiesDialog::slotItemChanged); 0119 m_listWidget->setSelectionMode(QAbstractItemView::NoSelection); 0120 const QList<KFileItemModel::RoleInfo> rolesInfo = KFileItemModel::rolesInformation(); 0121 for (const KFileItemModel::RoleInfo &info : rolesInfo) { 0122 QListWidgetItem *item = new QListWidgetItem(info.translation, m_listWidget); 0123 item->setCheckState(visibleRoles.contains(info.role) ? Qt::Checked : Qt::Unchecked); 0124 0125 const bool enable = 0126 ((!info.requiresBaloo && !info.requiresIndexer) || (info.requiresBaloo) || (info.requiresIndexer && indexingEnabled)) && info.role != "text"; 0127 0128 if (!enable) { 0129 item->setFlags(item->flags() & ~Qt::ItemIsEnabled); 0130 } 0131 } 0132 QLabel *additionalViewOptionsLabel = new QLabel(i18n("Choose what to see on each file or folder:")); 0133 innerLayout->addWidget(additionalViewOptionsLabel); 0134 innerLayout->addWidget(m_listWidget); 0135 } 0136 0137 QHBoxLayout *sortingLayout = new QHBoxLayout(); 0138 sortingLayout->setContentsMargins(0, 0, 0, 0); 0139 sortingLayout->addWidget(m_sortOrder); 0140 sortingLayout->addWidget(m_sorting); 0141 0142 layout->addRow(i18nc("@label:listbox", "View mode:"), m_viewMode); 0143 layout->addRow(i18nc("@label:listbox", "Sorting:"), sortingLayout); 0144 0145 layout->addItem(new QSpacerItem(0, Dolphin::VERTICAL_SPACER_HEIGHT, QSizePolicy::Fixed, QSizePolicy::Fixed)); 0146 0147 layout->addRow(i18n("View options:"), m_sortFoldersFirst); 0148 layout->addRow(QString(), m_previewsShown); 0149 layout->addRow(QString(), m_showInGroups); 0150 layout->addRow(QString(), m_showHiddenFiles); 0151 layout->addRow(QString(), m_sortHiddenLast); 0152 0153 connect(m_viewMode, &QComboBox::currentIndexChanged, this, &ViewPropertiesDialog::slotViewModeChanged); 0154 connect(m_sorting, &QComboBox::currentIndexChanged, this, &ViewPropertiesDialog::slotSortingChanged); 0155 connect(m_sortOrder, &QComboBox::currentIndexChanged, this, &ViewPropertiesDialog::slotSortOrderChanged); 0156 connect(m_sortFoldersFirst, &QCheckBox::clicked, this, &ViewPropertiesDialog::slotSortFoldersFirstChanged); 0157 connect(m_sortHiddenLast, &QCheckBox::clicked, this, &ViewPropertiesDialog::slotSortHiddenLastChanged); 0158 connect(m_previewsShown, &QCheckBox::clicked, this, &ViewPropertiesDialog::slotShowPreviewChanged); 0159 connect(m_showInGroups, &QCheckBox::clicked, this, &ViewPropertiesDialog::slotGroupedSortingChanged); 0160 connect(m_showHiddenFiles, &QCheckBox::clicked, this, &ViewPropertiesDialog::slotShowHiddenFilesChanged); 0161 0162 // Only show the following settings if the view properties are remembered 0163 // for each directory: 0164 if (!useGlobalViewProps) { 0165 // create 'Apply View Properties To' group 0166 m_applyToCurrentFolder = new QRadioButton(i18nc("@option:radio Apply View Properties To", "Current folder")); 0167 m_applyToCurrentFolder->setChecked(true); 0168 m_applyToSubFolders = new QRadioButton(i18nc("@option:radio Apply View Properties To", "Current folder and sub-folders")); 0169 m_applyToAllFolders = new QRadioButton(i18nc("@option:radio Apply View Properties To", "All folders")); 0170 0171 QButtonGroup *applyGroup = new QButtonGroup(this); 0172 applyGroup->addButton(m_applyToCurrentFolder); 0173 applyGroup->addButton(m_applyToSubFolders); 0174 applyGroup->addButton(m_applyToAllFolders); 0175 0176 layout->addItem(new QSpacerItem(0, Dolphin::VERTICAL_SPACER_HEIGHT, QSizePolicy::Fixed, QSizePolicy::Fixed)); 0177 0178 layout->addRow(i18nc("@title:group", "Apply to:"), m_applyToCurrentFolder); 0179 layout->addRow(QString(), m_applyToSubFolders); 0180 layout->addRow(QString(), m_applyToAllFolders); 0181 layout->addRow(QString(), m_applyToAllFolders); 0182 0183 m_useAsDefault = new QCheckBox(i18nc("@option:check", "Use as default view settings"), this); 0184 layout->addRow(QString(), m_useAsDefault); 0185 0186 connect(m_applyToCurrentFolder, &QRadioButton::clicked, this, &ViewPropertiesDialog::markAsDirty); 0187 connect(m_applyToSubFolders, &QRadioButton::clicked, this, &ViewPropertiesDialog::markAsDirty); 0188 connect(m_applyToAllFolders, &QRadioButton::clicked, this, &ViewPropertiesDialog::markAsDirty); 0189 connect(m_useAsDefault, &QCheckBox::clicked, this, &ViewPropertiesDialog::markAsDirty); 0190 } 0191 0192 layout->addItem(new QSpacerItem(0, Dolphin::VERTICAL_SPACER_HEIGHT, QSizePolicy::Fixed, QSizePolicy::Fixed)); 0193 0194 layout->addRow(additionalInfoBox); 0195 0196 auto buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel | QDialogButtonBox::Apply, this); 0197 connect(buttonBox, &QDialogButtonBox::accepted, this, &ViewPropertiesDialog::accept); 0198 connect(buttonBox, &QDialogButtonBox::rejected, this, &ViewPropertiesDialog::reject); 0199 layout->addWidget(buttonBox); 0200 0201 auto okButton = buttonBox->button(QDialogButtonBox::Ok); 0202 okButton->setShortcut(Qt::CTRL | Qt::Key_Return); 0203 okButton->setDefault(true); 0204 0205 auto applyButton = buttonBox->button(QDialogButtonBox::Apply); 0206 applyButton->setEnabled(false); 0207 connect(applyButton, &QPushButton::clicked, this, &ViewPropertiesDialog::slotApply); 0208 connect(this, &ViewPropertiesDialog::isDirtyChanged, applyButton, [applyButton](bool isDirty) { 0209 applyButton->setEnabled(isDirty); 0210 }); 0211 0212 const KConfigGroup dialogConfig(KSharedConfig::openConfig(QStringLiteral("dolphinrc")), QStringLiteral("ViewPropertiesDialog")); 0213 KWindowConfig::restoreWindowSize(windowHandle(), dialogConfig); 0214 0215 loadSettings(); 0216 } 0217 0218 ViewPropertiesDialog::~ViewPropertiesDialog() 0219 { 0220 m_isDirty = false; 0221 delete m_viewProps; 0222 m_viewProps = nullptr; 0223 0224 KConfigGroup dialogConfig(KSharedConfig::openConfig(QStringLiteral("dolphinrc")), QStringLiteral("ViewPropertiesDialog")); 0225 KWindowConfig::saveWindowSize(windowHandle(), dialogConfig); 0226 } 0227 0228 void ViewPropertiesDialog::accept() 0229 { 0230 applyViewProperties(); 0231 QDialog::accept(); 0232 } 0233 0234 void ViewPropertiesDialog::slotApply() 0235 { 0236 applyViewProperties(); 0237 markAsDirty(false); 0238 } 0239 0240 void ViewPropertiesDialog::slotViewModeChanged(int index) 0241 { 0242 const QVariant itemData = m_viewMode->itemData(index); 0243 const DolphinView::Mode viewMode = static_cast<DolphinView::Mode>(itemData.toInt()); 0244 m_viewProps->setViewMode(viewMode); 0245 markAsDirty(true); 0246 } 0247 0248 void ViewPropertiesDialog::slotSortingChanged(int index) 0249 { 0250 const QByteArray role = m_sorting->itemData(index).toByteArray(); 0251 m_viewProps->setSortRole(role); 0252 markAsDirty(true); 0253 } 0254 0255 void ViewPropertiesDialog::slotSortOrderChanged(int index) 0256 { 0257 const Qt::SortOrder sortOrder = (index == 0) ? Qt::AscendingOrder : Qt::DescendingOrder; 0258 m_viewProps->setSortOrder(sortOrder); 0259 markAsDirty(true); 0260 } 0261 0262 void ViewPropertiesDialog::slotGroupedSortingChanged() 0263 { 0264 m_viewProps->setGroupedSorting(m_showInGroups->isChecked()); 0265 markAsDirty(true); 0266 } 0267 0268 void ViewPropertiesDialog::slotSortFoldersFirstChanged() 0269 { 0270 const bool foldersFirst = m_sortFoldersFirst->isChecked(); 0271 m_viewProps->setSortFoldersFirst(foldersFirst); 0272 markAsDirty(true); 0273 } 0274 0275 void ViewPropertiesDialog::slotSortHiddenLastChanged() 0276 { 0277 const bool hiddenLast = m_sortHiddenLast->isChecked(); 0278 m_viewProps->setSortHiddenLast(hiddenLast); 0279 markAsDirty(true); 0280 } 0281 0282 void ViewPropertiesDialog::slotShowPreviewChanged() 0283 { 0284 const bool show = m_previewsShown->isChecked(); 0285 m_viewProps->setPreviewsShown(show); 0286 markAsDirty(true); 0287 } 0288 0289 void ViewPropertiesDialog::slotShowHiddenFilesChanged() 0290 { 0291 const bool show = m_showHiddenFiles->isChecked(); 0292 m_viewProps->setHiddenFilesShown(show); 0293 markAsDirty(true); 0294 } 0295 0296 void ViewPropertiesDialog::slotItemChanged(QListWidgetItem *item) 0297 { 0298 Q_UNUSED(item) 0299 markAsDirty(true); 0300 } 0301 0302 void ViewPropertiesDialog::markAsDirty(bool isDirty) 0303 { 0304 if (m_isDirty != isDirty) { 0305 m_isDirty = isDirty; 0306 Q_EMIT isDirtyChanged(isDirty); 0307 } 0308 } 0309 0310 void ViewPropertiesDialog::applyViewProperties() 0311 { 0312 // if nothing changed in the dialog, we have nothing to apply 0313 if (!m_isDirty) { 0314 return; 0315 } 0316 0317 // Update visible roles. 0318 { 0319 QList<QByteArray> visibleRoles; 0320 int index = 0; 0321 const QList<KFileItemModel::RoleInfo> rolesInfo = KFileItemModel::rolesInformation(); 0322 for (const KFileItemModel::RoleInfo &info : rolesInfo) { 0323 const QListWidgetItem *item = m_listWidget->item(index); 0324 if (item->checkState() == Qt::Checked) { 0325 visibleRoles.append(info.role); 0326 } 0327 ++index; 0328 } 0329 0330 m_viewProps->setVisibleRoles(visibleRoles); 0331 } 0332 0333 const bool applyToSubFolders = m_applyToSubFolders && m_applyToSubFolders->isChecked(); 0334 if (applyToSubFolders) { 0335 const QString text(i18nc("@info", "The view properties of all sub-folders will be changed. Do you want to continue?")); 0336 if (KMessageBox::questionTwoActions(this, text, {}, KStandardGuiItem::cont(), KStandardGuiItem::cancel()) == KMessageBox::SecondaryAction) { 0337 return; 0338 } 0339 0340 ViewPropsProgressInfo *info = new ViewPropsProgressInfo(m_dolphinView, m_dolphinView->url(), *m_viewProps); 0341 info->setAttribute(Qt::WA_DeleteOnClose); 0342 info->setWindowModality(Qt::NonModal); 0343 info->show(); 0344 } 0345 0346 const bool applyToAllFolders = m_applyToAllFolders && m_applyToAllFolders->isChecked(); 0347 0348 // If the user selected 'Apply To All Folders' the view properties implicitly 0349 // are also used as default for new folders. 0350 const bool useAsDefault = applyToAllFolders || (m_useAsDefault && m_useAsDefault->isChecked()); 0351 if (useAsDefault) { 0352 // For directories where no .directory file is available, the .directory 0353 // file stored for the global view properties is used as fallback. To update 0354 // this file we temporary turn on the global view properties mode. 0355 Q_ASSERT(!GeneralSettings::globalViewProps()); 0356 0357 GeneralSettings::setGlobalViewProps(true); 0358 ViewProperties defaultProps(m_dolphinView->url()); 0359 defaultProps.setDirProperties(*m_viewProps); 0360 defaultProps.save(); 0361 GeneralSettings::setGlobalViewProps(false); 0362 } 0363 0364 if (applyToAllFolders) { 0365 const QString text(i18nc("@info", "The view properties of all folders will be changed. Do you want to continue?")); 0366 if (KMessageBox::questionTwoActions(this, text, {}, KStandardGuiItem::cont(), KStandardGuiItem::cancel()) == KMessageBox::SecondaryAction) { 0367 return; 0368 } 0369 0370 // Updating the global view properties time stamp in the general settings makes 0371 // all existing viewproperties invalid, as they have a smaller time stamp. 0372 GeneralSettings *settings = GeneralSettings::self(); 0373 settings->setViewPropsTimestamp(QDateTime::currentDateTime()); 0374 settings->save(); 0375 } 0376 0377 m_dolphinView->setViewMode(m_viewProps->viewMode()); 0378 m_dolphinView->setSortRole(m_viewProps->sortRole()); 0379 m_dolphinView->setSortOrder(m_viewProps->sortOrder()); 0380 m_dolphinView->setSortFoldersFirst(m_viewProps->sortFoldersFirst()); 0381 m_dolphinView->setSortHiddenLast(m_viewProps->sortHiddenLast()); 0382 m_dolphinView->setGroupedSorting(m_viewProps->groupedSorting()); 0383 m_dolphinView->setVisibleRoles(m_viewProps->visibleRoles()); 0384 m_dolphinView->setPreviewsShown(m_viewProps->previewsShown()); 0385 m_dolphinView->setHiddenFilesShown(m_viewProps->hiddenFilesShown()); 0386 0387 m_viewProps->save(); 0388 0389 markAsDirty(false); 0390 } 0391 0392 void ViewPropertiesDialog::loadSettings() 0393 { 0394 // Load view mode 0395 switch (m_viewProps->viewMode()) { 0396 case DolphinView::IconsView: 0397 m_viewMode->setCurrentIndex(0); 0398 break; 0399 case DolphinView::CompactView: 0400 m_viewMode->setCurrentIndex(1); 0401 break; 0402 case DolphinView::DetailsView: 0403 m_viewMode->setCurrentIndex(2); 0404 break; 0405 default: 0406 break; 0407 } 0408 0409 // Load sort order and sorting 0410 const int sortOrderIndex = (m_viewProps->sortOrder() == Qt::AscendingOrder) ? 0 : 1; 0411 m_sortOrder->setCurrentIndex(sortOrderIndex); 0412 0413 const QList<KFileItemModel::RoleInfo> rolesInfo = KFileItemModel::rolesInformation(); 0414 int sortRoleIndex = 0; 0415 for (int i = 0; i < rolesInfo.count(); ++i) { 0416 if (rolesInfo[i].role == m_viewProps->sortRole()) { 0417 sortRoleIndex = i; 0418 break; 0419 } 0420 } 0421 m_sorting->setCurrentIndex(sortRoleIndex); 0422 0423 m_sortFoldersFirst->setChecked(m_viewProps->sortFoldersFirst()); 0424 m_sortHiddenLast->setChecked(m_viewProps->sortHiddenLast()); 0425 0426 // Load show preview, show in groups and show hidden files settings 0427 m_previewsShown->setChecked(m_viewProps->previewsShown()); 0428 m_showInGroups->setChecked(m_viewProps->groupedSorting()); 0429 m_showHiddenFiles->setChecked(m_viewProps->hiddenFilesShown()); 0430 markAsDirty(false); 0431 } 0432 0433 #include "moc_viewpropertiesdialog.cpp"