File indexing completed on 2024-05-19 04:55:51
0001 /** 0002 * \file kdemainwindow.cpp 0003 * KDE Kid3 main window. 0004 * 0005 * \b Project: Kid3 0006 * \author Urs Fleisch 0007 * \date 9 Jan 2003 0008 * 0009 * Copyright (C) 2003-2024 Urs Fleisch 0010 * 0011 * This file is part of Kid3. 0012 * 0013 * Kid3 is free software; you can redistribute it and/or modify 0014 * it under the terms of the GNU General Public License as published by 0015 * the Free Software Foundation; either version 2 of the License, or 0016 * (at your option) any later version. 0017 * 0018 * Kid3 is distributed in the hope that it will be useful, 0019 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0020 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0021 * GNU General Public License for more details. 0022 * 0023 * You should have received a copy of the GNU General Public License 0024 * along with this program. If not, see <http://www.gnu.org/licenses/>. 0025 */ 0026 0027 #include "kdemainwindow.h" 0028 #include <kconfigwidgets_version.h> 0029 #include <kconfig_version.h> 0030 #include <KToggleAction> 0031 #include <KStandardAction> 0032 #include <KShortcutsDialog> 0033 #include <KRecentFilesAction> 0034 #include <KActionCollection> 0035 #include <KEditToolBar> 0036 #include <KConfigSkeleton> 0037 #include <QApplication> 0038 #include <QUrl> 0039 #include <QAction> 0040 #include "config.h" 0041 #include "kid3form.h" 0042 #include "filelist.h" 0043 #include "sectionactions.h" 0044 #include "kid3application.h" 0045 #include "kdeconfigdialog.h" 0046 #include "guiconfig.h" 0047 #include "tagconfig.h" 0048 #include "useractionsconfig.h" 0049 #include "serverimporter.h" 0050 #include "servertrackimporter.h" 0051 0052 /** 0053 * Constructor. 0054 * 0055 * @param platformTools platform specific tools 0056 * @param app application context 0057 * @param parent parent widget 0058 */ 0059 KdeMainWindow::KdeMainWindow(IPlatformTools* platformTools, 0060 Kid3Application* app, QWidget* parent) 0061 : KXmlGuiWindow(parent), 0062 BaseMainWindow(this, platformTools, app), 0063 m_platformTools(platformTools), m_fileOpenRecent(nullptr), 0064 m_settingsShowStatusbar(nullptr), 0065 m_settingsAutoHideTags(nullptr), m_settingsShowHidePicture(nullptr) 0066 { 0067 init(); 0068 } 0069 0070 /** Only defined for generation of translation files */ 0071 #define MAIN_TOOLBAR_FOR_PO QT_TRANSLATE_NOOP("@default", "Main Toolbar") 0072 0073 /** 0074 * Init menu and toolbar actions. 0075 */ 0076 void KdeMainWindow::initActions() 0077 { 0078 KActionCollection* collection = actionCollection(); 0079 #if KCONFIGWIDGETS_VERSION >= 0x051700 0080 QAction* action = KStandardAction::open( 0081 impl(), &BaseMainWindowImpl::slotFileOpen, collection); 0082 #else 0083 QAction* action = KStandardAction::open( 0084 impl(), SLOT(slotFileOpen()), collection); 0085 #endif 0086 action->setStatusTip(tr("Open files")); 0087 #if KCONFIGWIDGETS_VERSION >= 0x051700 0088 m_fileOpenRecent = KStandardAction::openRecent( 0089 this, &KdeMainWindow::slotFileOpenRecentUrl, collection); 0090 #else 0091 m_fileOpenRecent = KStandardAction::openRecent( 0092 this, SLOT(slotFileOpenRecentUrl(QUrl)), collection); 0093 #endif 0094 m_fileOpenRecent->setStatusTip(tr("Opens a recently used folder")); 0095 #if KCONFIGWIDGETS_VERSION >= 0x051700 0096 action = KStandardAction::revert( 0097 app(), &Kid3Application::revertFileModifications, collection); 0098 #else 0099 action = KStandardAction::revert( 0100 app(), SLOT(revertFileModifications()), collection); 0101 #endif 0102 action->setStatusTip( 0103 tr("Reverts the changes of all or the selected files")); 0104 collection->setDefaultShortcuts(action, 0105 KStandardShortcut::shortcut(KStandardShortcut::Undo)); 0106 #if KCONFIGWIDGETS_VERSION >= 0x051700 0107 action = KStandardAction::save( 0108 impl(), &BaseMainWindowImpl::slotFileSave, collection); 0109 #else 0110 action = KStandardAction::save( 0111 impl(), SLOT(slotFileSave()), collection); 0112 #endif 0113 action->setStatusTip(tr("Saves the changed files")); 0114 #if KCONFIGWIDGETS_VERSION >= 0x051700 0115 action = KStandardAction::quit( 0116 impl(), &BaseMainWindowImpl::slotFileQuit, collection); 0117 #else 0118 action = KStandardAction::quit( 0119 impl(), SLOT(slotFileQuit()), collection); 0120 #endif 0121 action->setStatusTip(tr("Quits the application")); 0122 #if KCONFIGWIDGETS_VERSION >= 0x051700 0123 action = KStandardAction::selectAll( 0124 form(), &Kid3Form::selectAllFiles, collection); 0125 #else 0126 action = KStandardAction::selectAll( 0127 form(), SLOT(selectAllFiles()), collection); 0128 #endif 0129 action->setStatusTip(tr("Select all files")); 0130 action->setShortcut(QKeySequence(QLatin1String("Alt+Shift+A"))); 0131 #if KCONFIGWIDGETS_VERSION >= 0x051700 0132 action = KStandardAction::deselect( 0133 form(), &Kid3Form::deselectAllFiles, collection); 0134 #else 0135 action = KStandardAction::deselect( 0136 form(), SLOT(deselectAllFiles()), collection); 0137 #endif 0138 action->setStatusTip(tr("Deselect all files")); 0139 #if KCONFIGWIDGETS_VERSION >= 0x051700 0140 action = KStandardAction::find( 0141 impl(), &BaseMainWindowImpl::find, collection); 0142 #else 0143 action = KStandardAction::find( 0144 impl(), SLOT(find()), collection); 0145 #endif 0146 action->setStatusTip(tr("Find")); 0147 #if KCONFIGWIDGETS_VERSION >= 0x051700 0148 action = KStandardAction::replace( 0149 impl(), &BaseMainWindowImpl::findReplace, collection); 0150 #else 0151 action = KStandardAction::replace( 0152 impl(), SLOT(findReplace()), collection); 0153 #endif 0154 action->setStatusTip(tr("Find and replace")); 0155 setStandardToolBarMenuEnabled(true); 0156 createStandardStatusBarAction(); 0157 #if KCONFIGWIDGETS_VERSION >= 0x051700 0158 action = KStandardAction::keyBindings( 0159 this, &KdeMainWindow::slotSettingsShortcuts, collection); 0160 #else 0161 action = KStandardAction::keyBindings( 0162 this, SLOT(slotSettingsShortcuts()), collection); 0163 #endif 0164 action->setStatusTip(tr("Configure Shortcuts")); 0165 #if KCONFIGWIDGETS_VERSION >= 0x051700 0166 action = KStandardAction::configureToolbars( 0167 this, &KdeMainWindow::slotSettingsToolbars, collection); 0168 #else 0169 action = KStandardAction::configureToolbars( 0170 this, SLOT(slotSettingsToolbars()), collection); 0171 #endif 0172 action->setStatusTip(tr("Configure Toolbars")); 0173 #if KCONFIGWIDGETS_VERSION >= 0x051700 0174 m_settingsShowStatusbar = KStandardAction::showStatusbar( 0175 this, &KdeMainWindow::slotSettingsShowStatusbar, collection); 0176 #else 0177 m_settingsShowStatusbar = KStandardAction::showStatusbar( 0178 this, SLOT(slotSettingsShowStatusbar()), collection); 0179 #endif 0180 m_settingsShowStatusbar->setStatusTip(tr("Enables/disables the statusbar")); 0181 #if KCONFIGWIDGETS_VERSION >= 0x051700 0182 action = KStandardAction::preferences( 0183 this, &KdeMainWindow::slotSettingsConfigure, collection); 0184 #else 0185 action = KStandardAction::preferences( 0186 this, SLOT(slotSettingsConfigure()), collection); 0187 #endif 0188 action->setStatusTip(tr("Preferences dialog")); 0189 0190 action = new QAction(QIcon::fromTheme(QLatin1String("document-open")), 0191 tr("O&pen Folder..."), this); 0192 action->setStatusTip(tr("Opens a folder")); 0193 action->setShortcut(QKeySequence(QLatin1String("Ctrl+D"))); 0194 collection->addAction(QLatin1String("open_directory"), action); 0195 connect(action, &QAction::triggered, 0196 impl(), &BaseMainWindowImpl::slotFileOpenDirectory); 0197 0198 action = new QAction(QIcon::fromTheme(QLatin1String("view-refresh")), 0199 tr("Re&load"), this); 0200 action->setStatusTip(tr("Reload folder")); 0201 // When using the KDE version on GNOME, a dialog appears "There are two 0202 // actions (Replace..., Reload) that want to use the same shortcut (Ctrl+R)". 0203 // Avoid this by assigning Qt::Key_F5 instead of QKeySequence::Refresh. 0204 // The section "Standard Shortcuts" in the QKeySequence documentation lists 0205 // F5 as a key for "Refresh" on all platforms. 0206 action->setShortcut(Qt::Key_F5); 0207 collection->addAction(QLatin1String("reload"), action); 0208 connect(action, &QAction::triggered, 0209 impl(), &BaseMainWindowImpl::slotFileReload); 0210 0211 action = new QAction(tr("Unload"), this); 0212 collection->addAction(QLatin1String("unload"), action); 0213 connect(action, &QAction::triggered, app(), &Kid3Application::unloadAllTags); 0214 0215 action = new QAction(QIcon::fromTheme(QLatin1String("document-import")), 0216 tr("&Import..."), this); 0217 action->setStatusTip(tr("Import from file or clipboard")); 0218 action->setData(-1); 0219 collection->addAction(QLatin1String("import"), action); 0220 connect(action, &QAction::triggered, impl(), &BaseMainWindowImpl::slotImport); 0221 0222 int importerIdx = 0; 0223 const auto sis = app()->getServerImporters(); 0224 for (const ServerImporter* si : sis) { 0225 QString serverName(QCoreApplication::translate("@default", si->name())); 0226 QString actionName = QString::fromLatin1(si->name()).toLower() 0227 .remove(QLatin1Char(' ')); 0228 if (int dotPos = actionName.indexOf(QLatin1Char('.')); dotPos != -1) 0229 actionName.truncate(dotPos); 0230 actionName = QLatin1String("import_") + actionName; 0231 action = new QAction(tr("Import from %1...").arg(serverName), this); 0232 action->setData(importerIdx); 0233 action->setStatusTip(tr("Import from %1").arg(serverName)); 0234 collection->addAction(actionName, action); 0235 connect(action, &QAction::triggered, impl(), &BaseMainWindowImpl::slotImport); 0236 ++importerIdx; 0237 } 0238 0239 const auto stis = app()->getServerTrackImporters(); 0240 for (const ServerTrackImporter* si : stis) { 0241 QString serverName(QCoreApplication::translate("@default", si->name())); 0242 QString actionName = QString::fromLatin1(si->name()).toLower() 0243 .remove(QLatin1Char(' ')); 0244 if (int dotPos = actionName.indexOf(QLatin1Char('.')); dotPos != -1) 0245 actionName.truncate(dotPos); 0246 actionName = QLatin1String("import_") + actionName; 0247 action = new QAction(tr("Import from %1...").arg(serverName), this); 0248 action->setStatusTip(tr("Import from %1").arg(serverName)); 0249 action->setData(importerIdx); 0250 collection->addAction(actionName, action); 0251 connect(action, &QAction::triggered, impl(), &BaseMainWindowImpl::slotImport); 0252 ++importerIdx; 0253 } 0254 0255 action = new QAction(tr("Import from Tags..."), this); 0256 action->setStatusTip(tr("Import from Tags")); 0257 collection->addAction(QLatin1String("import_tags"), action); 0258 connect(action, &QAction::triggered, impl(), &BaseMainWindowImpl::slotTagImport); 0259 0260 action = new QAction(tr("Automatic I&mport..."), this); 0261 action->setStatusTip(tr("Automatic import")); 0262 collection->addAction(QLatin1String("batch_import"), action); 0263 connect(action, &QAction::triggered, impl(), &BaseMainWindowImpl::slotBatchImport); 0264 0265 action = new QAction(tr("&Browse Cover Art..."), this); 0266 action->setStatusTip(tr("Browse album cover artwork")); 0267 collection->addAction(QLatin1String("browse_cover_art"), action); 0268 connect(action, &QAction::triggered, impl(), &BaseMainWindowImpl::slotBrowseCoverArt); 0269 action = new QAction(QIcon::fromTheme(QLatin1String("document-export")), 0270 tr("&Export..."), this); 0271 action->setStatusTip(tr("Export to file or clipboard")); 0272 collection->addAction(QLatin1String("export"), action); 0273 connect(action, &QAction::triggered, impl(), &BaseMainWindowImpl::slotExport); 0274 action = new QAction(QIcon::fromTheme(QLatin1String("view-media-playlist")), 0275 tr("&Create Playlist..."), this); 0276 action->setStatusTip(tr("Create M3U Playlist")); 0277 collection->addAction(QLatin1String("create_playlist"), action); 0278 connect(action, &QAction::triggered, impl(), &BaseMainWindowImpl::slotPlaylistDialog); 0279 action = new QAction(tr("Apply &Filename Format"), this); 0280 action->setStatusTip(tr("Apply Filename Format")); 0281 collection->addAction(QLatin1String("apply_filename_format"), action); 0282 connect(action, &QAction::triggered, app(), &Kid3Application::applyFilenameFormat); 0283 action = new QAction(tr("Apply &Tag Format"), this); 0284 action->setStatusTip(tr("Apply Tag Format")); 0285 collection->addAction(QLatin1String("apply_id3_format"), action); 0286 connect(action, &QAction::triggered, app(), &Kid3Application::applyTagFormat); 0287 action = new QAction(tr("Apply Text &Encoding"), this); 0288 action->setStatusTip(tr("Apply Text Encoding")); 0289 collection->addAction(QLatin1String("apply_text_encoding"), action); 0290 connect(action, &QAction::triggered, app(), &Kid3Application::applyTextEncoding); 0291 action = new QAction(tr("&Rename Folder..."), this); 0292 action->setStatusTip(tr("Rename Folder")); 0293 collection->addAction(QLatin1String("rename_directory"), action); 0294 connect(action, &QAction::triggered, impl(), &BaseMainWindowImpl::slotRenameDirectory); 0295 action = new QAction(tr("&Number Tracks..."), this); 0296 action->setStatusTip(tr("Number Tracks")); 0297 collection->addAction(QLatin1String("number_tracks"), action); 0298 connect(action, &QAction::triggered, impl(), &BaseMainWindowImpl::slotNumberTracks); 0299 action = new QAction(tr("F&ilter..."), this); 0300 action->setStatusTip(tr("Filter")); 0301 collection->addAction(QLatin1String("filter"), action); 0302 connect(action, &QAction::triggered, impl(), &BaseMainWindowImpl::slotFilter); 0303 if (const TagConfig& tagCfg = TagConfig::instance(); 0304 tagCfg.taggedFileFeatures() & TaggedFile::TF_ID3v24) { 0305 action = new QAction(tr("Convert ID3v2.3 to ID3v2.&4"), this); 0306 action->setStatusTip(tr("Convert ID3v2.3 to ID3v2.4")); 0307 collection->addAction(QLatin1String("convert_to_id3v24"), action); 0308 connect(action, &QAction::triggered, app(), &Kid3Application::convertToId3v24); 0309 if (tagCfg.taggedFileFeatures() & TaggedFile::TF_ID3v23) { 0310 action = new QAction(tr("Convert ID3v2.4 to ID3v2.&3"), this); 0311 action->setStatusTip(tr("Convert ID3v2.4 to ID3v2.3")); 0312 collection->addAction(QLatin1String("convert_to_id3v23"), action); 0313 connect(action, &QAction::triggered, app(), &Kid3Application::convertToId3v23); 0314 } 0315 } 0316 #ifdef HAVE_QTMULTIMEDIA 0317 action = new QAction(QIcon::fromTheme(QLatin1String("media-playback-start")), 0318 tr("&Play"), this); 0319 action->setStatusTip(tr("Play")); 0320 collection->addAction(QLatin1String("play"), action); 0321 connect(action, &QAction::triggered, app(), &Kid3Application::playAudio); 0322 #endif 0323 m_settingsShowHidePicture = new KToggleAction(tr("Show &Picture"), this); 0324 m_settingsShowHidePicture->setStatusTip(tr("Show Picture")); 0325 m_settingsShowHidePicture->setCheckable(true); 0326 collection->addAction(QLatin1String("hide_picture"), m_settingsShowHidePicture); 0327 connect(m_settingsShowHidePicture, &QAction::triggered, 0328 impl(), &BaseMainWindowImpl::slotSettingsShowHidePicture); 0329 m_settingsAutoHideTags = new KToggleAction(tr("Auto &Hide Tags"), this); 0330 m_settingsAutoHideTags->setStatusTip(tr("Auto Hide Tags")); 0331 m_settingsAutoHideTags->setCheckable(true); 0332 collection->addAction(QLatin1String("auto_hide_tags"), m_settingsAutoHideTags); 0333 connect(m_settingsAutoHideTags, &QAction::triggered, 0334 impl(), &BaseMainWindowImpl::slotSettingsAutoHideTags); 0335 action = new QAction(tr("Select All in &Folder"), this); 0336 action->setStatusTip(tr("Select all files in the current folder")); 0337 collection->addAction(QLatin1String("select_all_in_directory"), action); 0338 connect(action, &QAction::triggered, app(), &Kid3Application::selectAllInDirectory); 0339 action = new QAction(tr("&Invert Selection"), this); 0340 collection->addAction(QLatin1String("invert_selection"), action); 0341 connect(action, &QAction::triggered, app(), &Kid3Application::invertSelection); 0342 action = new QAction(QIcon::fromTheme(QLatin1String("go-previous")), 0343 tr("&Previous File"), this); 0344 action->setStatusTip(tr("Select previous file")); 0345 collection->setDefaultShortcuts(action, 0346 KStandardShortcut::shortcut(KStandardShortcut::Prior)); 0347 collection->addAction(QLatin1String("previous_file"), action); 0348 connect(action, &QAction::triggered, form(), &Kid3Form::selectPreviousTaggedFile); 0349 action = new QAction(QIcon::fromTheme(QLatin1String("go-next")), 0350 tr("&Next File"), this); 0351 action->setStatusTip(tr("Select next file")); 0352 collection->setDefaultShortcuts(action, 0353 KStandardShortcut::shortcut(KStandardShortcut::Next)); 0354 collection->addAction(QLatin1String("next_file"), action); 0355 connect(action, &QAction::triggered, form(), &Kid3Form::selectNextTaggedFile); 0356 FOR_ALL_TAGS(tagNr) { 0357 Frame::TagNumber otherTagNr = tagNr == Frame::Tag_1 0358 ? Frame::Tag_2 0359 : tagNr == Frame::Tag_2 ? Frame::Tag_1 : Frame::Tag_NumValues; 0360 QString tagStr = Frame::tagNumberToString(tagNr); 0361 Kid3ApplicationTagContext* appTag = app()->tag(tagNr); 0362 Kid3FormTagContext* formTag = form()->tag(tagNr); 0363 QString actionPrefix = tr("Tag %1").arg(tagStr) + 0364 QLatin1String(": "); 0365 action = new QAction(tr("Filename") + QLatin1String(": ") + 0366 tr("From Tag %1").arg(tagStr), this); 0367 collection->addAction(QLatin1String("filename_from_v") + tagStr, action); 0368 connect(action, &QAction::triggered, 0369 appTag, &Kid3ApplicationTagContext::getFilenameFromTags); 0370 tagStr = QLatin1Char('v') + tagStr + QLatin1Char('_'); 0371 action = new QAction(actionPrefix + tr("From Filename"), this); 0372 collection->addAction(tagStr + QLatin1String("from_filename"), action); 0373 connect(action, &QAction::triggered, 0374 appTag, &Kid3ApplicationTagContext::getTagsFromFilename); 0375 if (otherTagNr < Frame::Tag_NumValues) { 0376 QString otherTagStr = Frame::tagNumberToString(otherTagNr); 0377 action = new QAction(actionPrefix + tr("From Tag %1").arg(otherTagStr), 0378 this); 0379 collection->addAction(tagStr + QLatin1String("from_v") + otherTagStr, 0380 action); 0381 connect(action, &QAction::triggered, 0382 appTag, &Kid3ApplicationTagContext::copyToOtherTag); 0383 } 0384 action = new QAction(actionPrefix + tr("Copy"), this); 0385 collection->addAction(tagStr + QLatin1String("copy"), action); 0386 connect(action, &QAction::triggered, 0387 appTag, &Kid3ApplicationTagContext::copyTags); 0388 action = new QAction(actionPrefix + tr("Paste"), this); 0389 collection->addAction(tagStr + QLatin1String("paste"), action); 0390 connect(action, &QAction::triggered, 0391 appTag, &Kid3ApplicationTagContext::pasteTags); 0392 action = new QAction(actionPrefix + tr("Remove"), this); 0393 collection->addAction(tagStr + QLatin1String("remove"), action); 0394 connect(action, &QAction::triggered, 0395 appTag, &Kid3ApplicationTagContext::removeTags); 0396 action = new QAction(actionPrefix + tr("Focus"), this); 0397 collection->addAction(tagStr + QLatin1String("focus"), action); 0398 connect(action, &QAction::triggered, 0399 formTag, &Kid3FormTagContext::setFocusTag); 0400 if (tagNr != Frame::Tag_Id3v1) { 0401 actionPrefix += tr("Frames:") + QLatin1Char(' '); 0402 action = new QAction(actionPrefix + tr("Edit"), this); 0403 collection->addAction(tagStr + QLatin1String("frames_edit"), action); 0404 connect(action, &QAction::triggered, 0405 appTag, &Kid3ApplicationTagContext::editFrame); 0406 action = new QAction(actionPrefix + tr("Add"), this); 0407 collection->addAction(tagStr + QLatin1String("frames_add"), action); 0408 connect(action, &QAction::triggered, 0409 appTag, &Kid3ApplicationTagContext::addFrame); 0410 action = new QAction(actionPrefix + tr("Delete"), this); 0411 collection->addAction(tagStr + QLatin1String("frames_delete"), action); 0412 connect(action, &QAction::triggered, 0413 appTag, &Kid3ApplicationTagContext::deleteFrame); 0414 } 0415 } 0416 0417 action = new QAction(tr("Filename") + QLatin1String(": ") + tr("Focus"), 0418 this); 0419 collection->addAction(QLatin1String("filename_focus"), action); 0420 connect(action, &QAction::triggered, form(), &Kid3Form::setFocusFilename); 0421 0422 action = new QAction(tr("File List") + QLatin1String(": ") + tr("Focus"), 0423 this); 0424 collection->addAction(QLatin1String("filelist_focus"), action); 0425 connect(action, &QAction::triggered, form(), &Kid3Form::setFocusFileList); 0426 action = new QAction(tr("&Rename"), this); 0427 action->setShortcut(QKeySequence(Qt::Key_F2)); 0428 action->setShortcutContext(Qt::WidgetShortcut); 0429 connect(action, &QAction::triggered, impl(), &BaseMainWindowImpl::renameFile); 0430 // This action is not made configurable because its shortcut F2 conflicts 0431 // with a section shortcut and there seems to be no way to avoid it with 0432 // KShortcutsDialog. The same applies to the shortcut with the Delete key. 0433 // collection->addAction(QLatin1String("filelist_rename"), action); 0434 form()->getFileList()->setRenameAction(action); 0435 action = new QAction(tr("&Move to Trash"), this); 0436 action->setShortcut(QKeySequence::Delete); 0437 action->setShortcutContext(Qt::WidgetShortcut); 0438 connect(action, &QAction::triggered, impl(), &BaseMainWindowImpl::deleteFile); 0439 // collection->addAction(QLatin1String("filelist_delete"), action); 0440 form()->getFileList()->setDeleteAction(action); 0441 action = new QAction(tr("Folder List") + QLatin1String(": ") + tr("Focus"), 0442 this); 0443 collection->addAction(QLatin1String("dirlist_focus"), action); 0444 connect(action, &QAction::triggered, form(), &Kid3Form::setFocusDirList); 0445 0446 FileList* fileList = form()->getFileList(); 0447 // Do not support user action keyboard shortcuts with KDE 4, it would only 0448 // print "Attempt to use QAction (..) with KXMLGUIFactory!" warnings. 0449 connect(fileList, &FileList::userActionAdded, 0450 this, &KdeMainWindow::onUserActionAdded); 0451 connect(fileList, &FileList::userActionRemoved, 0452 this, &KdeMainWindow::onUserActionRemoved); 0453 fileList->initUserActions(); 0454 const UserActionsConfig& userActionsCfg = UserActionsConfig::instance(); 0455 connect(&userActionsCfg, &UserActionsConfig::contextMenuCommandsChanged, 0456 fileList, &FileList::initUserActions); 0457 0458 const auto sectionShortcuts = SectionActions::defaultShortcuts(); 0459 QString actionPrefix = tr("Section") + QLatin1String(": "); 0460 for (auto it = sectionShortcuts.constBegin(); 0461 it != sectionShortcuts.constEnd(); 0462 ++it) { 0463 const auto& tpl = *it; 0464 action = new QAction(actionPrefix + std::get<1>(tpl), this); 0465 action->setShortcutContext(Qt::WidgetShortcut); 0466 // The action is only used to configure the shortcuts. Disabling it will 0467 // also avoid "that want to use the same shortcut" error dialogs. 0468 action->setEnabled(false); 0469 collection->setDefaultShortcut(action, std::get<2>(tpl)); 0470 collection->addAction(std::get<0>(tpl), action); 0471 } 0472 0473 actionPrefix = tr("Player") + QLatin1String(": "); 0474 const auto actions = impl()->mediaActions(); 0475 for (QAction* mediaAction : actions) { 0476 mediaAction->setText(actionPrefix + mediaAction->text()); 0477 collection->addAction(mediaAction->objectName(), mediaAction); 0478 } 0479 0480 createGUI(); 0481 } 0482 0483 /** 0484 * Get keyboard shortcuts. 0485 * @return mapping of action names to key sequences. 0486 */ 0487 QMap<QString, QKeySequence> KdeMainWindow::shortcutsMap() const 0488 { 0489 QMap<QString, QKeySequence> map; 0490 if (KActionCollection* collection = actionCollection()) { 0491 const auto actions = collection->actions(); 0492 for (QAction* action : actions) { 0493 if (action) { 0494 if (QString name = action->objectName(); !name.isEmpty()) { 0495 map.insert(name, action->shortcut()); 0496 } 0497 } 0498 } 0499 } 0500 return map; 0501 } 0502 0503 /** 0504 * Add directory to recent files list. 0505 * 0506 * @param dirName path to directory 0507 */ 0508 void KdeMainWindow::addDirectoryToRecentFiles(const QString& dirName) 0509 { 0510 QUrl url; 0511 url.setPath(dirName); 0512 m_fileOpenRecent->addUrl(url); 0513 } 0514 0515 /** 0516 * Read settings from the configuration. 0517 */ 0518 void KdeMainWindow::readConfig() 0519 { 0520 auto cfg = KSharedConfig::openConfig(); 0521 #if KCONFIG_VERSION >= 0x054300 0522 auto stateCfg = KSharedConfig::openStateConfig(); 0523 #else 0524 auto stateCfg = cfg; 0525 #endif 0526 setAutoSaveSettings(stateCfg->group("MainWindow")); 0527 m_settingsShowHidePicture->setChecked(!GuiConfig::instance().hidePicture()); 0528 m_settingsAutoHideTags->setChecked(GuiConfig::instance().autoHideTags()); 0529 m_fileOpenRecent->loadEntries(stateCfg->group("Recent Files")); 0530 0531 QString entry = cfg->group("MainWindow").readEntry("StatusBar", "Enabled"); 0532 bool statusBarVisible = entry != QLatin1String("Disabled"); 0533 if (m_settingsShowStatusbar) { 0534 m_settingsShowStatusbar->setChecked(statusBarVisible); 0535 } 0536 setStatusBarVisible(statusBarVisible); 0537 } 0538 0539 /** 0540 * Store geometry and recent files in settings. 0541 */ 0542 void KdeMainWindow::saveConfig() 0543 { 0544 #if KCONFIG_VERSION >= 0x054300 0545 auto stateCfg = KSharedConfig::openStateConfig(); 0546 #else 0547 auto stateCfg = KSharedConfig::openConfig(); 0548 #endif 0549 m_fileOpenRecent->saveEntries(stateCfg->group("Recent Files")); 0550 } 0551 0552 /** 0553 * Set main window caption. 0554 * 0555 * @param caption caption without application name 0556 * @param modified true if any file is modified 0557 */ 0558 void KdeMainWindow::setWindowCaption(const QString& caption, bool modified) 0559 { 0560 setCaption(caption, modified); 0561 } 0562 0563 /** 0564 * Get action for Settings/Auto Hide Tags. 0565 * @return action. 0566 */ 0567 QAction* KdeMainWindow::autoHideTagsAction() 0568 { 0569 return m_settingsAutoHideTags; 0570 } 0571 0572 /** 0573 * Get action for Settings/Hide Picture. 0574 * @return action. 0575 */ 0576 QAction* KdeMainWindow::showHidePictureAction() 0577 { 0578 return m_settingsShowHidePicture; 0579 } 0580 0581 /** 0582 * Update modification state before closing. 0583 * Called on closeEvent() of window. 0584 * If anything was modified, save after asking user. 0585 * Save options before closing. 0586 * This method is called by closeEvent(), which occurs when the 0587 * window is closed or slotFileQuit() (Quit menu) is selected. 0588 * 0589 * @return false if user canceled, 0590 * true will quit the application. 0591 */ 0592 bool KdeMainWindow::queryClose() 0593 { 0594 return queryBeforeClosing(); 0595 } 0596 0597 /** 0598 * Saves the window properties to the session config file. 0599 * 0600 * @param cfg application configuration 0601 */ 0602 void KdeMainWindow::saveProperties(KConfigGroup& cfg) 0603 { 0604 cfg.writeEntry("dirname", app()->getDirName()); 0605 } 0606 0607 /** 0608 * Reads the session config file and restores the application's state. 0609 * 0610 * @param cfg application configuration 0611 */ 0612 void KdeMainWindow::readProperties(const KConfigGroup& cfg) 0613 { 0614 app()->openDirectory({cfg.readEntry("dirname", "")}); 0615 } 0616 0617 /** 0618 * Open recent directory. 0619 * 0620 * @param url URL of directory to open 0621 */ 0622 void KdeMainWindow::slotFileOpenRecentUrl(const QUrl& url) 0623 { 0624 openRecentDirectory(url.path()); 0625 } 0626 0627 /** 0628 * Shortcuts configuration. 0629 */ 0630 void KdeMainWindow::slotSettingsShortcuts() 0631 { 0632 #if KCONFIGWIDGETS_VERSION >= 0x05f000 0633 KShortcutsDialog::showDialog( 0634 actionCollection(), 0635 KShortcutsEditor::LetterShortcutsAllowed, this); 0636 impl()->applyChangedShortcuts(); 0637 #else 0638 if (KShortcutsDialog::configure( 0639 actionCollection(), 0640 KShortcutsEditor::LetterShortcutsAllowed, this) == 0641 QDialog::Accepted) { 0642 impl()->applyChangedShortcuts(); 0643 } 0644 #endif 0645 } 0646 0647 /** 0648 * Toolbars configuration. 0649 */ 0650 void KdeMainWindow::slotSettingsToolbars() 0651 { 0652 if (KEditToolBar dlg(actionCollection()); dlg.exec()) { 0653 createGUI(); 0654 } 0655 } 0656 0657 /** 0658 * Statusbar configuration. 0659 */ 0660 void KdeMainWindow::slotSettingsShowStatusbar() 0661 { 0662 setStatusBarVisible(m_settingsShowStatusbar->isChecked()); 0663 setSettingsDirty(); 0664 } 0665 0666 /** 0667 * Preferences. 0668 */ 0669 void KdeMainWindow::slotSettingsConfigure() 0670 { 0671 QString caption(tr("Configure - Kid3")); 0672 auto configSkeleton = new KConfigSkeleton; 0673 auto dialog = new KdeConfigDialog(m_platformTools, this, caption, 0674 configSkeleton); 0675 dialog->setConfig(); 0676 if (dialog->exec() == QDialog::Accepted) { 0677 dialog->getConfig(); 0678 impl()->applyChangedConfiguration(); 0679 } 0680 delete configSkeleton; 0681 } 0682 0683 /** 0684 * Add user action to collection. 0685 * @param name name of action 0686 * @param action action to add 0687 */ 0688 void KdeMainWindow::onUserActionAdded(const QString& name, QAction* action) 0689 { 0690 KActionCollection* collection = actionCollection(); 0691 collection->addAction(name, action); 0692 } 0693 0694 /** 0695 * Remove user action from collection. 0696 * @param name name of action 0697 * @param action action to remove 0698 */ 0699 void KdeMainWindow::onUserActionRemoved(const QString& name, QAction* action) 0700 { 0701 Q_UNUSED(name) 0702 KActionCollection* collection = actionCollection(); 0703 collection->takeAction(action); 0704 }