File indexing completed on 2024-05-19 05:06:01
0001 /*********************************************************************************** 0002 Copyright (C) 2011-2012 by Holger Danielsson (holger.danielsson@versanet.de) 0003 (C) 2018 by Michel Ludwig (michel.ludwig@kdemail.net) 0004 ***********************************************************************************/ 0005 0006 /*************************************************************************** 0007 * * 0008 * This program is free software; you can redistribute it and/or modify * 0009 * it under the terms of the GNU General Public License as published by * 0010 * the Free Software Foundation; either version 2 of the License, or * 0011 * (at your option) any later version. * 0012 * * 0013 ***************************************************************************/ 0014 0015 #include <QDialogButtonBox> 0016 #include <QFileDialog> 0017 #include <QInputDialog> 0018 #include <QKeySequence> 0019 #include <QPushButton> 0020 #include <QVBoxLayout> 0021 0022 #include <KLocalizedString> 0023 #include <KIconDialog> 0024 #include <KMessageBox> 0025 #include <KXMLGUIClient> 0026 #include <KXMLGUIFactory> 0027 #include <KConfigGroup> 0028 0029 #include "dialogs/usermenu/usermenudialog.h" 0030 #include "dialogs/usermenu/usermenutree.h" 0031 #include "dialogs/usermenu/usermenuitem.h" 0032 #include "usermenu/usermenu.h" 0033 0034 #include "kiledebug.h" 0035 #include "utilities.h" 0036 0037 namespace KileMenu { 0038 0039 #define CHOOSABLE_MENUTYPES 3 0040 0041 UserMenuDialog::UserMenuDialog(KConfig *config, KileInfo *ki, KileMenu::UserMenu *userMenu, const QString &xmlfile, QWidget *parent) 0042 : KileDialog::Wizard(config, parent, Q_NULLPTR, i18n("Edit User Menu")) 0043 , m_ki(ki) 0044 , m_userMenu(userMenu) 0045 { 0046 QWidget *page = new QWidget(); 0047 QVBoxLayout *mainLayout = new QVBoxLayout; 0048 setLayout(mainLayout); 0049 0050 m_UserMenuDialog.setupUi(page); 0051 0052 m_menutree = m_UserMenuDialog.m_twUserMenu; 0053 m_menutree->setHeaderLabels(QStringList() << i18n("Menu Entry") << i18n("Shortcut")); 0054 0055 // Indexes must be identical to MenuType. Only the first three of them are choosable (see CHOOSABLE_MENUTYPES) 0056 m_listMenutypes << i18n("Text") << i18n("Insert file contents") << i18n("Execute program") << i18n("Separator") << i18n("Submenu"); 0057 0058 // some text 0059 m_UserMenuDialog.m_teText->setWhatsThis(i18n("Text, which will be inserted, if the action is executed. Some placeholders are available: <ul><li>%M - selected (marked) text</li><li>%C - cursor position</li><li>%B - bullet</li><li>%E - indentation in environments</li><li>%R - select label from list</li><li>%T - select citation key from list</li></ul>")); 0060 m_UserMenuDialog.m_teText->setToolTip(i18n("Available placeholders:\n%M: Selected (marked) text\n%C: Cursor position\n%B: Bullet\n%E: Indentation in environments\n%R: Select label from list\n%T: Select citation key from list\n%S: Source file name without extension")); 0061 0062 // search for all action collections (needed for shortcut conflicts) 0063 QList<KActionCollection *> allCollections; 0064 foreach (KXMLGUIClient *client, m_ki->mainWindow()->guiFactory()->clients()) { 0065 KILE_DEBUG_MAIN << "collection count: " << client->actionCollection()->count() ; 0066 allCollections += client->actionCollection(); 0067 } 0068 m_UserMenuDialog.m_keyChooser->setCheckActionCollections(allCollections); 0069 KILE_DEBUG_MAIN << "total collections: " << allCollections.count(); 0070 0071 m_UserMenuDialog.m_pbInsertBelow->setIcon(QIcon::fromTheme("usermenu-insert-below.png")); 0072 m_UserMenuDialog.m_pbInsertSubmenu->setIcon(QIcon::fromTheme("usermenu-submenu-below.png")); 0073 m_UserMenuDialog.m_pbInsertSeparator->setIcon(QIcon::fromTheme("usermenu-separator-below.png")); 0074 m_UserMenuDialog.m_pbDelete->setIcon(QIcon::fromTheme("usermenu-delete.png")); 0075 m_UserMenuDialog.m_pbUp->setIcon(QIcon::fromTheme("usermenu-up.png")); 0076 m_UserMenuDialog.m_pbDown->setIcon(QIcon::fromTheme("usermenu-down.png")); 0077 m_UserMenuDialog.m_pbIconDelete->setIcon(QIcon::fromTheme("edit-clear-locationbar-rtl.png")); 0078 0079 connect(m_UserMenuDialog.m_pbInsertBelow, &QPushButton::clicked, this, &UserMenuDialog::slotInsertMenuItem); 0080 connect(m_UserMenuDialog.m_pbInsertSubmenu, &QPushButton::clicked, this, &UserMenuDialog::slotInsertSubmenu); 0081 connect(m_UserMenuDialog.m_pbInsertSeparator, &QPushButton::clicked, this, &UserMenuDialog::slotInsertSeparator); 0082 connect(m_UserMenuDialog.m_pbUp, &QPushButton::clicked, this, &UserMenuDialog::slotUp); 0083 connect(m_UserMenuDialog.m_pbDown, &QPushButton::clicked, this, &UserMenuDialog::slotDown); 0084 connect(m_UserMenuDialog.m_pbDelete, &QPushButton::clicked, this, &UserMenuDialog::slotDelete); 0085 0086 connect(m_menutree, &QTreeWidget::currentItemChanged, this, &UserMenuDialog::slotCurrentItemChanged); 0087 0088 connect(m_UserMenuDialog.m_pbMenuentryType, &QPushButton::clicked, this, &UserMenuDialog::slotMenuentryTypeClicked); 0089 connect(m_UserMenuDialog.m_leMenuEntry, &KLineEdit::textEdited, this, &UserMenuDialog::slotMenuentryTextChanged); 0090 connect(m_UserMenuDialog.m_urlRequester, &KUrlRequester::textChanged, this, &UserMenuDialog::slotUrlTextChanged); 0091 connect(m_UserMenuDialog.m_urlRequester, &KUrlRequester::urlSelected, this, [=]() { 0092 setModified(); 0093 }); 0094 connect(m_UserMenuDialog.m_leParameter, &KLineEdit::textEdited, this, [=]() { 0095 setModified(); 0096 }); 0097 connect(m_UserMenuDialog.m_teText, &QPlainTextEdit::textChanged, this, [=]() { 0098 setModified(); 0099 }); 0100 connect(m_UserMenuDialog.m_pbIcon, &QPushButton::clicked, this, &UserMenuDialog::slotIconClicked); 0101 connect(m_UserMenuDialog.m_pbIconDelete, &QPushButton::clicked, this, &UserMenuDialog::slotIconDeleteClicked); 0102 connect(m_UserMenuDialog.m_keyChooser, &KKeySequenceWidget::keySequenceChanged, this, &UserMenuDialog::slotKeySequenceChanged); 0103 0104 connect(m_UserMenuDialog.m_cbNeedsSelection, &QCheckBox::stateChanged, this, &UserMenuDialog::slotSelectionStateChanged); 0105 connect(m_UserMenuDialog.m_cbContextMenu, &QCheckBox::stateChanged, this, &UserMenuDialog::slotCheckboxStateChanged); 0106 connect(m_UserMenuDialog.m_cbReplaceSelection, &QCheckBox::stateChanged, this, &UserMenuDialog::slotCheckboxStateChanged); 0107 connect(m_UserMenuDialog.m_cbSelectInsertion, &QCheckBox::stateChanged, this, &UserMenuDialog::slotCheckboxStateChanged); 0108 connect(m_UserMenuDialog.m_cbInsertOutput, &QCheckBox::stateChanged, this, &UserMenuDialog::slotCheckboxStateChanged); 0109 0110 connect(m_UserMenuDialog.m_pbInstall, &QPushButton::clicked, this, &UserMenuDialog::slotInstallClicked); 0111 connect(m_UserMenuDialog.m_pbNew, &QPushButton::clicked, this, &UserMenuDialog::slotNewClicked); 0112 0113 connect(m_UserMenuDialog.m_pbLoad, &QPushButton::clicked, this, &UserMenuDialog::slotLoadClicked); 0114 connect(m_UserMenuDialog.m_pbSave, &QPushButton::clicked, this, &UserMenuDialog::slotSaveClicked); 0115 connect(m_UserMenuDialog.m_pbSaveAs, &QPushButton::clicked, this, &UserMenuDialog::slotSaveAsClicked); 0116 0117 // set context menu handler for the menutree 0118 m_menutree->setContextMenuPolicy(Qt::CustomContextMenu); 0119 connect(m_menutree, &QWidget::customContextMenuRequested, this, &UserMenuDialog::slotCustomContextMenuRequested); 0120 0121 // adjust some widths 0122 const int w = m_UserMenuDialog.m_pbInsertBelow->sizeHint().width(); 0123 m_UserMenuDialog.m_pbUp->setMinimumWidth(w); 0124 m_UserMenuDialog.m_pbDown->setMinimumWidth(w); 0125 m_UserMenuDialog.m_lbIconChosen->setMinimumWidth(m_UserMenuDialog.m_pbIcon->sizeHint().width()); 0126 0127 setFocusProxy(m_menutree); 0128 setModal(false); 0129 0130 // TODO: currently all dialog actions are in an extra widget 0131 // for usability some of those actions should be connect to the main dialog controls, 0132 // e.g. automatic install when pressing OK 0133 buttonBox()->clear(); 0134 buttonBox()->addButton(QDialogButtonBox::Close); 0135 buttonBox()->addButton(QDialogButtonBox::Help); 0136 0137 mainLayout->addWidget(page); 0138 mainLayout->addWidget(buttonBox()); 0139 connect(buttonBox(), &QDialogButtonBox::helpRequested, this, &UserMenuDialog::slotShowHelp); 0140 0141 KILE_DEBUG_MAIN << "start dialog with xmfile " << xmlfile; 0142 0143 if (!xmlfile.isEmpty() && QFile::exists(xmlfile)) { 0144 m_modified = false; 0145 loadXmlFile(xmlfile,true); 0146 } 0147 else { 0148 startDialog(); 0149 } 0150 0151 resize(minimumSize()); 0152 } 0153 0154 void UserMenuDialog::startDialog() 0155 { 0156 initDialog(); 0157 0158 m_modified = false; 0159 setXmlFile(QString(), false); 0160 updateDialogButtons(); 0161 m_UserMenuDialog.m_pbNew->setEnabled(false); 0162 } 0163 0164 void UserMenuDialog::initDialog() 0165 { 0166 updateTreeButtons(); 0167 0168 QTreeWidgetItem *current = m_menutree->currentItem(); 0169 if (current) { 0170 m_menutree->setCurrentItem(current); 0171 } 0172 0173 // init first entry 0174 m_currentIcon.clear(); 0175 showMenuentryData(dynamic_cast<UserMenuItem *>(current)); 0176 } 0177 0178 void UserMenuDialog::setXmlFile(const QString &filename, bool installed) 0179 { 0180 m_currentXmlInstalled = installed; 0181 m_currentXmlFile = filename; 0182 m_UserMenuDialog.m_lbXmlFile->setText(i18n("File:") + QLatin1String(" ") + QFileInfo(m_currentXmlFile).fileName()); 0183 if (m_currentXmlInstalled) { 0184 m_UserMenuDialog.m_lbXmlInstalled->show(); 0185 } else { 0186 m_UserMenuDialog.m_lbXmlInstalled->hide(); 0187 } 0188 } 0189 0190 void UserMenuDialog::setModified() 0191 { 0192 if (!m_modified) { 0193 m_modified = true; 0194 } 0195 0196 updateDialogButtons(); 0197 } 0198 0199 void UserMenuDialog::updateDialogButtons() 0200 { 0201 bool installedFile = (!m_currentXmlFile.isEmpty()); 0202 bool menutreeState = !m_menutree->isEmpty(); 0203 0204 bool installState = !m_modified && installedFile && !m_currentXmlInstalled; 0205 bool saveState = m_modified && installedFile; 0206 bool saveAsState = m_modified || (!m_modified && installedFile && m_currentXmlInstalled); 0207 0208 m_UserMenuDialog.m_pbInstall->setEnabled(installState && menutreeState); 0209 m_UserMenuDialog.m_pbSave->setEnabled(saveState && menutreeState); 0210 m_UserMenuDialog.m_pbSaveAs->setEnabled(saveAsState && menutreeState); 0211 m_UserMenuDialog.m_pbNew->setEnabled(true); 0212 } 0213 0214 void UserMenuDialog::slotShowHelp() 0215 { 0216 const QString message = i18n("<p>You can create, change and install a user-defined menu, which will appear as a part of Kile's menu. " 0217 "To create or change this menu, use the six buttons on the left side. " 0218 "Even more possible actions are available in the context menu of already existing menu items.</p>" 0219 "<p>Like a standard menu, three different kinds of menu items are available:</p>" 0220 "<ul>" 0221 "<li><i>standard entries</i>, which are assigned to an action</li>" 0222 "<li><i>submenus</i>, which contain more menu items</li>" 0223 "<li><i>separators</i>, to get a visible structure of all entries</li>" 0224 "</ul>" 0225 "<p>Each standard menu item is assigned to one of three action types:</p>" 0226 "<ul>" 0227 "<li><i>insert text</i>: this action will insert your text at the current cursor position. " 0228 "Some metachars are available: <tt>%M</tt>, <tt>%C</tt>, <tt>%B</tt>, <tt>%E</tt>, <tt>%R</tt>, <tt>%T</tt>, <tt>%S</tt>: " 0229 "see the <i>What's This</i> or <i>Tool Tip</i> feature of this widget to get more information.</li>" 0230 "<li><i>file content</i>: inserts the complete contents of a given file (metachars are also available)</li>" 0231 "<li><i>run an external program</i>: The output of this program can be inserted into the opened document. " 0232 "Metachar <tt>%M</tt> is also possible in the commandline of this program, as the selected text will be saved in a temporary file. " 0233 "Use <tt>%M</tt> for the filename of this temporary file.</li>" 0234 "</ul>" 0235 "<p>If some important information for an action is missing, menu items are colored red. " 0236 "More information is available using the <i>What's this</i> feature of most widgets.</p>"); 0237 0238 KMessageBox::information(this, message, i18n("UserMenu Dialog")); 0239 } 0240 0241 0242 ///////////////////////////// Button slots (Install/New) ////////////////////////////// 0243 0244 void UserMenuDialog::slotInstallClicked() 0245 { 0246 KILE_DEBUG_MAIN << "install " << m_currentXmlFile << "..."; 0247 0248 if (!m_modified && !m_currentXmlFile.isEmpty()) { 0249 m_userMenu->installXmlFile(m_currentXmlFile); 0250 setXmlFile(m_currentXmlFile,true); 0251 updateDialogButtons(); 0252 } 0253 } 0254 0255 void UserMenuDialog::slotNewClicked() 0256 { 0257 KILE_DEBUG_MAIN << "start new menutree ... "; 0258 0259 if (!m_menutree->isEmpty() && m_modified) { 0260 if (KMessageBox::questionTwoActions(this, i18n("Current menu tree was modified, but not saved.\nDiscard this tree?"), 0261 i18n("Discard tree"), 0262 KStandardGuiItem::discard(), KStandardGuiItem::cancel()) == KMessageBox::SecondaryAction) { 0263 return; 0264 } 0265 } 0266 0267 m_menutree->clear(); 0268 m_modified = false; 0269 startDialog(); // includes updating of buttons 0270 } 0271 0272 0273 ///////////////////////////// Button slots (Load) ////////////////////////////// 0274 0275 void UserMenuDialog::slotLoadClicked() 0276 { 0277 KILE_DEBUG_MAIN << "load xml file "; 0278 0279 if (!m_menutree->isEmpty() && m_modified) { 0280 if (KMessageBox::questionTwoActions(this, i18n("Current menu tree was modified, but not saved.\nDiscard this tree?"), 0281 i18n("Discard tree"), 0282 KStandardGuiItem::discard(), KStandardGuiItem::cancel()) == KMessageBox::SecondaryAction) { 0283 return; 0284 } 0285 } 0286 0287 QString directory = UserMenu::selectUserMenuDir(); 0288 QString filter = i18n("User Menu Files (*.xml)"); 0289 0290 QString filename = QFileDialog::getOpenFileName(this, i18n("Select Menu File"), directory, filter); 0291 if (filename.isEmpty()) { 0292 return; 0293 } 0294 0295 if (QFile::exists(filename)) { 0296 loadXmlFile(filename,false); // includes updating of buttons 0297 } 0298 else { 0299 KMessageBox::error(this, i18n("File '%1' does not exist.", filename)); 0300 } 0301 } 0302 0303 void UserMenuDialog::loadXmlFile(const QString &filename, bool installed) 0304 { 0305 KILE_DEBUG_MAIN << "load xml started ..."; 0306 m_menutree->readXml(filename); 0307 initDialog(); 0308 m_modified = false; 0309 setXmlFile(filename,installed); 0310 updateDialogButtons(); 0311 KILE_DEBUG_MAIN << "load xml finished ..."; 0312 } 0313 0314 ///////////////////////////// Button slots (Save) ////////////////////////////// 0315 0316 void UserMenuDialog::slotSaveClicked() 0317 { 0318 if (saveClicked()) { 0319 m_modified = false; 0320 if (m_currentXmlInstalled) { 0321 slotInstallClicked(); // includes all updates 0322 } 0323 else { 0324 setXmlFile(m_currentXmlFile,false); 0325 } 0326 updateDialogButtons(); 0327 } 0328 } 0329 0330 bool UserMenuDialog::saveClicked() 0331 { 0332 if (m_currentXmlFile.isEmpty()) { 0333 return false; 0334 } 0335 KILE_DEBUG_MAIN << "save menutree: " << m_currentXmlFile; 0336 0337 // read current entry 0338 QTreeWidgetItem *current = m_menutree->currentItem(); 0339 if (current) { 0340 KILE_DEBUG_MAIN << "read current item ..."; 0341 readMenuentryData( dynamic_cast<UserMenuItem *>(current) ); 0342 } 0343 0344 if (saveCheck() == false) { 0345 return false; 0346 } 0347 0348 // force to save file in local directory 0349 QStringList dirs = KileUtilities::locateAll(QStandardPaths::AppDataLocation, "usermenu", QStandardPaths::LocateDirectory); 0350 if (dirs.size() > 1) { 0351 if (m_currentXmlFile.startsWith(dirs[1])) { 0352 m_currentXmlFile.replace(dirs[1],dirs[0]); 0353 KILE_DEBUG_MAIN << "change filename to local directory:" << m_currentXmlFile; 0354 } 0355 } 0356 0357 // save file 0358 m_menutree->writeXml(m_currentXmlFile); 0359 return true; 0360 } 0361 0362 void UserMenuDialog::slotSaveAsClicked() 0363 { 0364 const QString filename = saveAsClicked(); 0365 if (!filename.isEmpty()) { 0366 // set new state: current file is not installed anymore 0367 m_modified = false; 0368 setXmlFile(filename,false); 0369 updateDialogButtons(); 0370 } 0371 } 0372 0373 QString UserMenuDialog::saveAsClicked() 0374 { 0375 KILE_DEBUG_MAIN << "menutree should be saved as ..."; 0376 0377 // read current entry 0378 QTreeWidgetItem *current = m_menutree->currentItem(); 0379 if (current) { 0380 KILE_DEBUG_MAIN << "read current item ..."; 0381 readMenuentryData(dynamic_cast<UserMenuItem *>(current)); 0382 } 0383 0384 if (saveCheck() == false) { 0385 return QString(); 0386 } 0387 0388 const QString directory = KileUtilities::writableLocation(QStandardPaths::AppDataLocation) + QLatin1Char('/') + "usermenu/"; 0389 const QString filter = i18n("User Menu Files (*.xml)"); 0390 0391 QString filename = QFileDialog::getSaveFileName(this, i18n("Save Menu File"), directory, filter); 0392 if (filename.isEmpty()) { 0393 return QString(); 0394 } 0395 0396 if (QFile::exists(filename)) { 0397 if (KMessageBox::questionTwoActions(this, i18n("File '%1' does already exist.\nOverwrite this file?", filename), 0398 i18n("Overwrite file"), 0399 KStandardGuiItem::overwrite(), KStandardGuiItem::cancel()) == KMessageBox::SecondaryAction) { 0400 return QString(); 0401 } 0402 } 0403 0404 // save file 0405 m_menutree->writeXml(filename); 0406 return filename; 0407 } 0408 0409 bool UserMenuDialog::saveCheck() 0410 { 0411 if (m_menutree->errorCheck() == false) { 0412 if (KMessageBox::questionTwoActions(this, i18n("The menu tree contains some errors and installing this file may lead to unpredictable results.\nDo you really want to save this file?"), 0413 i18n("Menu tree errors"), 0414 KStandardGuiItem::save(), KStandardGuiItem::cancel()) == KMessageBox::SecondaryAction) { 0415 return false; 0416 } 0417 } 0418 0419 return true; 0420 } 0421 0422 ///////////////////////////// Button slots (left widget) ////////////////////////////// 0423 0424 void UserMenuDialog::slotCustomContextMenuRequested(const QPoint &pos) 0425 { 0426 m_menutree->contextMenuRequested(pos); 0427 updateAfterDelete(); 0428 } 0429 0430 void UserMenuDialog::slotInsertMenuItem() 0431 { 0432 if (m_menutree->insertMenuItem(m_menutree->currentItem())) { 0433 updateTreeButtons(); 0434 setModified(); 0435 } 0436 } 0437 0438 void UserMenuDialog::slotInsertSubmenu() 0439 { 0440 QTreeWidgetItem *current = m_menutree->currentItem(); 0441 if (current && m_menutree->insertSubmenu(current)) { 0442 updateTreeButtons(); 0443 setModified(); 0444 } 0445 } 0446 0447 void UserMenuDialog::slotInsertSeparator() 0448 { 0449 QTreeWidgetItem *current = m_menutree->currentItem(); 0450 if (current && m_menutree->insertSeparator(current)) { 0451 updateTreeButtons(); 0452 setModified(); 0453 } 0454 } 0455 0456 void UserMenuDialog::slotDelete() 0457 { 0458 QTreeWidgetItem *current = m_menutree->currentItem(); 0459 if (current) { 0460 m_menutree->itemDelete(current); 0461 updateAfterDelete(); 0462 } 0463 } 0464 0465 void UserMenuDialog::slotUp() 0466 { 0467 QTreeWidgetItem *current = m_menutree->currentItem(); 0468 if (current) { 0469 m_menutree->itemUp(); 0470 updateTreeButtons(); 0471 setModified(); 0472 } 0473 } 0474 0475 void UserMenuDialog::slotDown() 0476 { 0477 QTreeWidgetItem *current = m_menutree->currentItem(); 0478 if (current) { 0479 m_menutree->itemDown(); 0480 updateTreeButtons(); 0481 setModified(); 0482 } 0483 } 0484 0485 void UserMenuDialog::updateTreeButtons() 0486 { 0487 UserMenuItem *current = dynamic_cast<UserMenuItem *>(m_menutree->currentItem()); 0488 if (current) { 0489 bool state = (current->menutype() == UserMenuData::Separator) ? false : true; 0490 m_UserMenuDialog.m_pbInsertSeparator->setEnabled(state); 0491 m_UserMenuDialog.m_pbDelete->setEnabled(true); 0492 0493 bool upstate = (m_menutree->indexOfTopLevelItem(current) == 0) ? false : true; 0494 m_UserMenuDialog.m_pbUp->setEnabled(upstate); 0495 0496 bool downstate = (m_menutree->itemBelow(current)) ? true : false; 0497 if (!downstate && current->parent()) { 0498 downstate = true; 0499 } 0500 m_UserMenuDialog.m_pbDown->setEnabled(downstate); 0501 } 0502 else { 0503 m_UserMenuDialog.m_pbInsertSeparator->setEnabled(false); 0504 m_UserMenuDialog.m_pbDelete->setEnabled(false); 0505 m_UserMenuDialog.m_pbUp->setEnabled(false); 0506 m_UserMenuDialog.m_pbDown->setEnabled(false); 0507 } 0508 } 0509 0510 void UserMenuDialog::updateAfterDelete() 0511 { 0512 if (m_menutree->isEmpty()) { 0513 initDialog(); 0514 } 0515 0516 updateTreeButtons(); 0517 setModified(); 0518 0519 } 0520 0521 ////////////////////////////// TreeWidget slots (left widget) ////////////////////////////// 0522 0523 void UserMenuDialog::slotCurrentItemChanged(QTreeWidgetItem *current,QTreeWidgetItem *previous) 0524 { 0525 QString from = (previous) ? previous->text(0) : "---"; 0526 QString to = (current) ? current->text(0) : "---"; 0527 0528 KILE_DEBUG_MAIN << "currentItemChanged: from=" << from << " to=" << to; 0529 bool modifiedState = m_modified; 0530 bool installState = m_UserMenuDialog.m_pbInstall->isEnabled(); 0531 bool saveState = m_UserMenuDialog.m_pbSave->isEnabled(); 0532 bool saveAsState = m_UserMenuDialog.m_pbSaveAs->isEnabled(); 0533 0534 // read old data 0535 readMenuentryData(dynamic_cast<UserMenuItem *>(previous)); 0536 0537 // set new data 0538 showMenuentryData(dynamic_cast<UserMenuItem *>(current)); 0539 0540 // update buttons for treewidget 0541 updateTreeButtons(); 0542 0543 // restore saved states 0544 m_modified = modifiedState; 0545 m_UserMenuDialog.m_pbInstall->setEnabled(installState); 0546 m_UserMenuDialog.m_pbSave->setEnabled(saveState); 0547 m_UserMenuDialog.m_pbSaveAs->setEnabled(saveAsState); 0548 } 0549 0550 ////////////////////////////// MenuentryType slots (right widget) ////////////////////////////// 0551 0552 void UserMenuDialog::slotMenuentryTypeClicked() 0553 { 0554 UserMenuItem *current = dynamic_cast<UserMenuItem *>(m_menutree->currentItem()); 0555 if (!current) { 0556 return; 0557 } 0558 0559 KILE_DEBUG_MAIN << "change menu item type of current item: " << current->text(0); 0560 QStringList typelist; 0561 for (int i = 0; i < CHOOSABLE_MENUTYPES; ++i) { 0562 typelist << m_listMenutypes[i]; 0563 } 0564 0565 int oldtype = current->menutype(); 0566 bool ok = false; 0567 0568 QString item = QInputDialog::getItem(this, i18n("Menutype"), i18n("Please choose a menutype"), 0569 typelist, oldtype, false, &ok); 0570 if (!ok) { 0571 return; 0572 } 0573 0574 int newtype = m_listMenutypes.indexOf(item); 0575 if (newtype == -1 || newtype == oldtype) { 0576 return; 0577 } 0578 0579 // set new values 0580 current->setMenutype( UserMenuData::MenuType(newtype) ); 0581 m_UserMenuDialog.m_lbMenuentryType->setText(item); 0582 if (newtype == UserMenuData::Text) { 0583 setMenuentryFileChooser(current,false); 0584 setMenuentryFileParameter(current,false); 0585 setMenuentryTextEdit(current,true); 0586 setMenuentryCheckboxes(current,false); 0587 } 0588 else if (newtype == UserMenuData::FileContent) { 0589 setMenuentryFileChooser(current,true); 0590 setMenuentryFileParameter(current,false); 0591 setMenuentryTextEdit(current,false); 0592 setMenuentryCheckboxes(current,false); 0593 } 0594 else { /* if (newtype == UserMenuData::Program) */ 0595 setMenuentryFileChooser(current,true); 0596 setMenuentryFileParameter(current,true); 0597 setMenuentryTextEdit(current,false); 0598 setMenuentryCheckboxes(current,true); 0599 } 0600 0601 setModified(); 0602 } 0603 0604 ////////////////////////////// Menuentry slot (right widget) ////////////////////////////// 0605 0606 void UserMenuDialog::slotMenuentryTextChanged(const QString &text) 0607 { 0608 UserMenuItem *current = dynamic_cast<UserMenuItem *>( m_menutree->currentItem() ); 0609 if (current) { 0610 current->setText(0,text); 0611 } 0612 setModified(); 0613 } 0614 0615 ////////////////////////////// KUrlRequester slots (right widget) ////////////////////////////// 0616 0617 void UserMenuDialog::slotUrlTextChanged(const QString &) 0618 { 0619 UserMenuItem *current = dynamic_cast<UserMenuItem *>(m_menutree->currentItem()); 0620 if (!current) { 0621 return; 0622 } 0623 0624 QString file = m_UserMenuDialog.m_urlRequester->text().trimmed(); 0625 0626 QString color = "black"; 0627 int type = current->menutype(); 0628 if (type == UserMenuData::FileContent) { 0629 if (file.isEmpty() || !QFile::exists(file)) { 0630 color = "red"; 0631 } 0632 } 0633 else if (type == UserMenuData::Program) { 0634 if (file.isEmpty() || !m_menutree->isItemExecutable(file)) { 0635 color= "red"; 0636 } 0637 } 0638 0639 m_UserMenuDialog.m_urlRequester->setStyleSheet( "QLineEdit { color: " + color + "; }" ); 0640 setModified(); 0641 } 0642 0643 ////////////////////////////// Icon slots (right widget) ////////////////////////////// 0644 0645 void UserMenuDialog::slotIconClicked() 0646 { 0647 QString iconname = KIconDialog::getIcon(KIconLoader::Small, KIconLoader::Any,true); 0648 if (iconname!=m_currentIcon && !iconname.isEmpty()) { 0649 QString iconpath = KIconLoader::global()->iconPath(iconname,KIconLoader::Small); 0650 KILE_DEBUG_MAIN << "icon changed: " << iconname << " path=" << iconpath; 0651 m_currentIcon = iconpath; 0652 setMenuentryIcon(m_currentIcon); 0653 setModified(); 0654 } 0655 } 0656 0657 void UserMenuDialog::slotIconDeleteClicked() 0658 { 0659 m_currentIcon.clear(); 0660 setMenuentryIcon(m_currentIcon); 0661 setModified(); 0662 } 0663 0664 void UserMenuDialog::setMenuentryIcon(const QString &icon) 0665 { 0666 UserMenuItem *current = dynamic_cast<UserMenuItem *>(m_menutree->currentItem()); 0667 if (current) { 0668 if (icon.isEmpty()) { 0669 current->setIcon(0, QIcon::fromTheme(QString())); 0670 } else { 0671 current->setIcon(0, QIcon::fromTheme(icon)); 0672 } 0673 current->setMenuicon(icon); 0674 0675 // update icon widgets 0676 setMenuentryIcon(current,true,icon); 0677 setModified(); 0678 } 0679 } 0680 0681 ////////////////////////////// Shortcut slots (right widget) ////////////////////////////// 0682 0683 void UserMenuDialog::slotKeySequenceChanged(const QKeySequence &seq) 0684 { 0685 QString shortcut = seq.toString(QKeySequence::NativeText); 0686 KILE_DEBUG_MAIN << "key sequence changed: " << shortcut; 0687 0688 UserMenuItem *current = dynamic_cast<UserMenuItem *>( m_menutree->currentItem() ); 0689 if (current) { 0690 current->setText(1, shortcut); 0691 current->setShortcut(shortcut); 0692 0693 m_UserMenuDialog.m_keyChooser->applyStealShortcut(); 0694 setModified(); 0695 } 0696 } 0697 0698 ////////////////////////////// Selection checkbox slots (right widget) ////////////////////////////// 0699 0700 void UserMenuDialog::slotSelectionStateChanged(int state) 0701 { 0702 m_UserMenuDialog.m_cbContextMenu->setEnabled(state); 0703 if(!state) { 0704 m_UserMenuDialog.m_cbContextMenu->setChecked(state); 0705 } 0706 setModified(); 0707 } 0708 0709 void UserMenuDialog::slotCheckboxStateChanged(int) 0710 { 0711 setModified(); 0712 } 0713 0714 ////////////////////////////// read menu item data ////////////////////////////// 0715 0716 void UserMenuDialog::readMenuentryData(UserMenuItem *item) 0717 { 0718 KILE_DEBUG_MAIN << "read current menu item ..."; 0719 if (!item) { 0720 return; 0721 } 0722 0723 UserMenuData::MenuType type = UserMenuData::MenuType( m_listMenutypes.indexOf(m_UserMenuDialog.m_lbMenuentryType->text()) ); 0724 item->setMenutype(type); 0725 if (type == UserMenuData::Separator) { 0726 return; 0727 } 0728 0729 item->setMenutitle(m_UserMenuDialog.m_leMenuEntry->text().trimmed()); 0730 item->setFilename(m_UserMenuDialog.m_urlRequester->text().trimmed()); 0731 item->setParameter(m_UserMenuDialog.m_leParameter->text().trimmed()); 0732 item->setPlaintext(m_UserMenuDialog.m_teText->toPlainText()); 0733 0734 item->setMenuicon(m_currentIcon); 0735 item->setShortcut(m_UserMenuDialog.m_keyChooser->keySequence().toString(QKeySequence::NativeText)); 0736 0737 item->setNeedsSelection(m_UserMenuDialog.m_cbNeedsSelection->checkState()); 0738 item->setUseContextMenu(m_UserMenuDialog.m_cbContextMenu->checkState()); 0739 item->setReplaceSelection(m_UserMenuDialog.m_cbReplaceSelection->checkState()); 0740 item->setSelectInsertion(m_UserMenuDialog.m_cbSelectInsertion->checkState()); 0741 item->setInsertOutput(m_UserMenuDialog.m_cbInsertOutput->checkState()); 0742 0743 bool executable = (type==UserMenuData::Program && m_menutree->isItemExecutable(item->filename())); 0744 item->setModelData(executable); 0745 0746 item->setText(0, item->updateMenutitle()); 0747 } 0748 0749 ////////////////////////////// show menu item data ////////////////////////////// 0750 0751 void UserMenuDialog::showMenuentryData(UserMenuItem *item) 0752 { 0753 KILE_DEBUG_MAIN << "show new menu item ..."; 0754 if (!item) { 0755 disableMenuEntryData(); 0756 return; 0757 } 0758 0759 UserMenuData::MenuType type = item->menutype(); 0760 0761 blockSignals(true); 0762 switch (type) { 0763 case UserMenuData::Text: 0764 setTextEntry(item); 0765 break; 0766 case UserMenuData::FileContent: 0767 setFileContentEntry(item); 0768 break; 0769 case UserMenuData::Program: 0770 setProgramEntry(item); 0771 break; 0772 case UserMenuData::Separator: 0773 setSeparatorEntry(item); 0774 break; 0775 case UserMenuData::Submenu: 0776 setSubmenuEntry(item); 0777 break; 0778 default: 0779 disableMenuEntryData(); // should not happen 0780 } 0781 blockSignals(false); 0782 } 0783 0784 void UserMenuDialog::setTextEntry(UserMenuItem *item) 0785 { 0786 setMenuentryText(item, true); 0787 setMenuentryType(item, true, true); 0788 setMenuentryFileChooser(item, false); 0789 setMenuentryFileParameter(item, false); 0790 setMenuentryTextEdit(item, true); 0791 setMenuentryIcon(item, true); 0792 setMenuentryShortcut(item, true); 0793 setParameterGroupbox(true); 0794 setMenuentryCheckboxes(item, false); 0795 } 0796 0797 void UserMenuDialog::setFileContentEntry(UserMenuItem *item) 0798 { 0799 setMenuentryText(item, true); 0800 setMenuentryType(item, true, true); 0801 setMenuentryFileChooser(item, true); 0802 setMenuentryFileParameter(item, false); 0803 setMenuentryTextEdit(item, false); 0804 setMenuentryIcon(item, true); 0805 setMenuentryShortcut(item, true); 0806 setParameterGroupbox(true); 0807 setMenuentryCheckboxes(item, false); 0808 } 0809 0810 void UserMenuDialog::setProgramEntry(UserMenuItem *item) 0811 { 0812 setMenuentryText(item, true); 0813 setMenuentryType(item, true, true); 0814 setMenuentryFileChooser(item, true); 0815 setMenuentryFileParameter(item, true); 0816 setMenuentryTextEdit(item, false); 0817 setMenuentryIcon(item, true); 0818 setMenuentryShortcut(item, true); 0819 setParameterGroupbox(true); 0820 setMenuentryCheckboxes(item, true); 0821 } 0822 0823 void UserMenuDialog::setSeparatorEntry(UserMenuItem *item) 0824 { 0825 disableMenuEntryData(); 0826 setMenuentryType(item, true, false); 0827 } 0828 0829 void UserMenuDialog::setSubmenuEntry(UserMenuItem *item) 0830 { 0831 setMenuentryText(item, true); 0832 setMenuentryType(item, true, false); 0833 setMenuentryFileChooser(Q_NULLPTR, false); 0834 setMenuentryFileParameter(Q_NULLPTR, false); 0835 setMenuentryTextEdit(Q_NULLPTR, false); 0836 setMenuentryIcon(Q_NULLPTR, false); 0837 setMenuentryShortcut(Q_NULLPTR, false); 0838 setParameterGroupbox(false); 0839 setMenuentryCheckboxes(Q_NULLPTR, false); 0840 } 0841 0842 ////////////////////////////// update data widgets////////////////////////////// 0843 0844 void UserMenuDialog::setMenuentryType(UserMenuItem *item, bool state1, bool state2) 0845 { 0846 const QString s = (item && state1) ? m_listMenutypes[item->menutype()] : QString(); 0847 m_UserMenuDialog.m_lbMenuentryType->setText(s); 0848 m_UserMenuDialog.m_lbMenuentryType->setEnabled(state1); 0849 m_UserMenuDialog.m_pbMenuentryType->setEnabled(state2); 0850 } 0851 0852 void UserMenuDialog::setMenuentryText(UserMenuItem *item, bool state) 0853 { 0854 const QString s = (item && state) ? item->menutitle() : QString(); 0855 m_UserMenuDialog.m_leMenuEntry->setText(s); 0856 0857 m_UserMenuDialog.m_lbMenuEntry->setEnabled(state); 0858 m_UserMenuDialog.m_leMenuEntry->setEnabled(state); 0859 } 0860 0861 void UserMenuDialog::setMenuentryFileChooser(UserMenuItem *item, bool state) 0862 { 0863 const QString s = (item && state) ? item->filename() : QString(); 0864 m_UserMenuDialog.m_urlRequester->setText(s); 0865 0866 m_UserMenuDialog.m_lbFile->setEnabled(state); 0867 m_UserMenuDialog.m_urlRequester->setEnabled(state); 0868 } 0869 0870 void UserMenuDialog::setMenuentryFileParameter(UserMenuItem *item, bool state) 0871 { 0872 const QString s = (item && state) ? item->parameter() : QString(); 0873 m_UserMenuDialog.m_leParameter->setText(s); 0874 0875 m_UserMenuDialog.m_lbParameter->setEnabled(state); 0876 m_UserMenuDialog.m_leParameter->setEnabled(state); 0877 0878 } 0879 0880 void UserMenuDialog::setMenuentryTextEdit(UserMenuItem *item, bool state) 0881 { 0882 const QString s = (item && state) ? item->plaintext() : QString(); 0883 m_UserMenuDialog.m_teText->setPlainText(s); 0884 0885 m_UserMenuDialog.m_lbText->setEnabled(state); 0886 m_UserMenuDialog.m_teText->setEnabled(state); 0887 } 0888 0889 void UserMenuDialog::setMenuentryIcon(UserMenuItem *item, bool state, const QString &icon) 0890 { 0891 if (item && state) { 0892 m_currentIcon = (icon.isEmpty()) ? item->menuicon() : icon; 0893 } 0894 else { 0895 m_currentIcon.clear(); 0896 } 0897 0898 // update widgets 0899 if (m_currentIcon.isEmpty()) { 0900 m_UserMenuDialog.m_lbIconChosen->setText(m_currentIcon); 0901 m_UserMenuDialog.m_lbIconChosen->hide(); 0902 m_UserMenuDialog.m_pbIcon->show(); 0903 } 0904 else { 0905 QString iconpath = KIconLoader::global()->iconPath(m_currentIcon,KIconLoader::Small); 0906 m_UserMenuDialog.m_lbIconChosen->setText("<img src=\"" + iconpath +"\" />"); 0907 m_UserMenuDialog.m_lbIconChosen->show(); 0908 m_UserMenuDialog.m_pbIcon->hide(); 0909 } 0910 0911 m_UserMenuDialog.m_lbIcon->setEnabled(state); 0912 m_UserMenuDialog.m_pbIcon->setEnabled(state); 0913 m_UserMenuDialog.m_lbIconChosen->setEnabled(state); 0914 bool deleteIconState = ( state && !m_currentIcon.isEmpty() ); 0915 m_UserMenuDialog.m_pbIconDelete->setEnabled(deleteIconState); 0916 } 0917 0918 void UserMenuDialog::setMenuentryShortcut(UserMenuItem *item, bool state) 0919 { 0920 if (item && state) { 0921 QString shortcut = item->shortcut(); 0922 if (shortcut.isEmpty()) { 0923 m_UserMenuDialog.m_keyChooser->clearKeySequence(); 0924 } 0925 else { 0926 m_UserMenuDialog.m_keyChooser->setKeySequence(QKeySequence(shortcut)); 0927 } 0928 item->setText(1, shortcut); 0929 } 0930 else { 0931 m_UserMenuDialog.m_keyChooser->clearKeySequence(); 0932 } 0933 0934 m_UserMenuDialog.m_lbShortcut->setEnabled(state); 0935 m_UserMenuDialog.m_keyChooser->setEnabled(state); 0936 } 0937 0938 void UserMenuDialog::setParameterGroupbox(bool state) 0939 { 0940 m_UserMenuDialog.m_gbParameter->setEnabled(state); 0941 } 0942 0943 void UserMenuDialog::setMenuentryCheckboxes(UserMenuItem *item, bool useInsertOutput) 0944 { 0945 bool selectionState, insertionState, outputState, replaceState, contextState; 0946 if (item) { 0947 selectionState = item->needsSelection(); 0948 replaceState = item->replaceSelection(); 0949 insertionState = item->selectInsertion(); 0950 outputState = (useInsertOutput) ? item->insertOutput() : false; 0951 contextState = (selectionState) ? item->useContextMenu() : false; 0952 } 0953 else { 0954 selectionState = false; 0955 replaceState = false; 0956 insertionState = false; 0957 outputState = false; 0958 contextState = false; 0959 } 0960 0961 // m_cbNeedsSelection and m_cbSelectInsertion are always enabled 0962 m_UserMenuDialog.m_cbNeedsSelection->setChecked(selectionState); 0963 0964 // m_cbContextMenu needs a selection to be enabled 0965 m_UserMenuDialog.m_cbContextMenu->setEnabled(selectionState); 0966 0967 m_UserMenuDialog.m_cbContextMenu->setChecked(contextState); 0968 m_UserMenuDialog.m_cbReplaceSelection->setChecked(replaceState); 0969 m_UserMenuDialog.m_cbSelectInsertion->setChecked(insertionState); 0970 m_UserMenuDialog.m_cbInsertOutput->setChecked(outputState); 0971 m_UserMenuDialog.m_cbInsertOutput->setEnabled(useInsertOutput); 0972 } 0973 0974 void UserMenuDialog::clearMenuEntryData() 0975 { 0976 m_UserMenuDialog.m_leMenuEntry->clear(); 0977 m_UserMenuDialog.m_lbMenuentryType->clear(); 0978 m_UserMenuDialog.m_urlRequester->clear(); 0979 m_UserMenuDialog.m_teText->clear(); 0980 m_UserMenuDialog.m_pbIcon->setIcon(QIcon::fromTheme(i18n("Choose"))); 0981 m_UserMenuDialog.m_keyChooser->clearKeySequence(); 0982 0983 m_UserMenuDialog.m_cbNeedsSelection->setChecked(false); 0984 m_UserMenuDialog.m_cbReplaceSelection->setChecked(false); 0985 m_UserMenuDialog.m_cbContextMenu->setChecked(false); 0986 m_UserMenuDialog.m_cbSelectInsertion->setChecked(false); 0987 m_UserMenuDialog.m_cbInsertOutput->setChecked(false); 0988 } 0989 0990 void UserMenuDialog::disableMenuEntryData() 0991 { 0992 setMenuentryText(Q_NULLPTR, false); 0993 setMenuentryType(Q_NULLPTR, false, false); 0994 setMenuentryFileChooser(Q_NULLPTR, false); 0995 setMenuentryFileParameter(Q_NULLPTR, false); 0996 setMenuentryTextEdit(Q_NULLPTR, false); 0997 setMenuentryIcon(Q_NULLPTR, false); 0998 setMenuentryShortcut(Q_NULLPTR, false); 0999 setParameterGroupbox(false); 1000 setMenuentryCheckboxes(Q_NULLPTR, false); 1001 } 1002 1003 }