File indexing completed on 2024-04-21 05:03:21
0001 /************************************************************************************** 0002 begin : 2003-07-01 17:33:00 CEST 2003 0003 copyright : (C) 2003 by Jeroen Wijnhout (Jeroen.Wijnhout@kdemail.net) 0004 2008-2016 by Michel Ludwig (michel.ludwig@kdemail.net) 0005 **************************************************************************************/ 0006 0007 /*************************************************************************** 0008 * * 0009 * This program is free software; you can redistribute it and/or modify * 0010 * it under the terms of the GNU General Public License as published by * 0011 * the Free Software Foundation; either version 2 of the License, or * 0012 * (at your option) any later version. * 0013 * * 0014 ***************************************************************************/ 0015 0016 // 2005-07-26 dani 0017 // - cleanup dialog 0018 // - added new action 'ShowLabel' 0019 0020 // 2007-03-12 dani 0021 // - use KileDocument::Extensions 0022 0023 #include "kileactions.h" 0024 0025 #include <QCheckBox> 0026 #include <QFileInfo> 0027 #include <QGridLayout> 0028 #include <QLabel> 0029 #include <QLayout> 0030 #include <QLineEdit> 0031 #include <QPushButton> 0032 #include <QString> 0033 #include <QStringList> 0034 #include <QToolBar> 0035 0036 #include <QMenu> 0037 0038 #include <KComboBox> 0039 #include <KCompletion> 0040 #include <KLocalizedString> 0041 #include <KConfigGroup> 0042 #include <QDialogButtonBox> 0043 #include <QVBoxLayout> 0044 #include <QFileDialog> 0045 0046 #include "kiledebug.h" 0047 #include "kileextensions.h" 0048 #include "kileinfo.h" 0049 #include "kiledocmanager.h" 0050 0051 namespace KileAction 0052 { 0053 0054 //////////////// 0055 // Tag // 0056 //////////////// 0057 Tag::Tag(const QString &text, const QString& iconText, const QKeySequence &shortcut, const QObject *receiver, const char *slot, KActionCollection *parent, 0058 const QString& name, const QString &tagBegin, const QString &tagEnd, 0059 int dx, int dy, const QString &description) 0060 : QAction(text, parent), 0061 m_data(text,tagBegin, tagEnd, dx, dy, description) 0062 { 0063 parent->addAction(name, this); 0064 setIconText(iconText); 0065 if(!shortcut.isEmpty()) { 0066 parent->setDefaultShortcut(this, shortcut); 0067 } 0068 init(receiver, slot); 0069 } 0070 0071 Tag::Tag(const QString &text, const QString& iconText, const QString& pix, const QKeySequence &shortcut, const QObject *receiver, const char *slot, KActionCollection *parent, 0072 const QString& name, const QString &tagBegin, const QString &tagEnd, 0073 int dx, int dy, const QString &description) 0074 : QAction(QIcon::fromTheme(pix), text, parent), 0075 m_data(text,tagBegin, tagEnd, dx, dy, description) 0076 { 0077 parent->addAction(name, this); 0078 setIconText(iconText); 0079 if(!shortcut.isEmpty()) { 0080 parent->setDefaultShortcut(this, shortcut); 0081 } 0082 init(receiver,slot); 0083 } 0084 0085 Tag::Tag(const QString &text, const QString& iconText, const QKeySequence &shortcut, const QObject *receiver, const char *slot, KActionCollection *parent, 0086 const QString& name, const TagData& data) 0087 : QAction(text, parent), 0088 m_data(data) 0089 { 0090 parent->addAction(name, this); 0091 setIconText(iconText); 0092 if(!shortcut.isEmpty()) { 0093 parent->setDefaultShortcut(this, shortcut); 0094 } 0095 init(receiver,slot); 0096 } 0097 0098 Tag::Tag(const QString &text, const QString& iconText, const QString& pix, const QKeySequence &shortcut, const QObject *receiver, const char *slot, KActionCollection *parent, 0099 const QString& name, const TagData& data) 0100 : QAction(QIcon::fromTheme(pix), text, parent), 0101 m_data(data) 0102 { 0103 parent->addAction(name, this); 0104 if(!shortcut.isEmpty()) { 0105 parent->setDefaultShortcut(this, shortcut); 0106 } 0107 setIconText(iconText); 0108 init(receiver,slot); 0109 } 0110 0111 Tag::~Tag() 0112 { 0113 } 0114 0115 void Tag::init(const QObject *receiver, const char *slot) 0116 { 0117 connect(this, SIGNAL(triggered()), SLOT(emitData())); 0118 connect(this, SIGNAL(triggered(KileAction::TagData)), receiver, slot); 0119 } 0120 0121 void Tag::emitData() 0122 { 0123 emit(triggered(m_data)); 0124 } 0125 0126 //////////////// 0127 // InputTag // 0128 //////////////// 0129 InputTag::InputTag(KileInfo* ki, const QString &text, const QString &iconText, const QKeySequence &cut, const QObject *receiver, const char *slot, KActionCollection *parent, const QString& name, QWidget *wparent, uint options, 0130 const QString &tagBegin, const QString &tagEnd, 0131 int dx, int dy, const QString &description, const QString &hint, const QString &alter) 0132 : Tag(text, iconText, cut, receiver, slot, parent, name, tagBegin, tagEnd, dx, dy, description), m_ki(ki), 0133 m_parent(wparent), m_options(options), m_hint(hint), m_alter(alter) 0134 { 0135 init(); 0136 } 0137 0138 InputTag::InputTag(KileInfo* ki, const QString &text, const QString &iconText, const QString& pix, const QKeySequence &cut, const QObject *receiver, const char *slot, KActionCollection *parent, const QString& name, QWidget *wparent, uint options, 0139 const QString &tagBegin, const QString &tagEnd, 0140 int dx, int dy, const QString &description, const QString &hint, const QString &alter) 0141 : Tag(text, iconText, pix, cut, receiver, slot, parent, name, tagBegin, tagEnd, dx, dy, description), m_ki(ki), 0142 m_parent(wparent), m_options(options), m_hint(hint), m_alter(alter) 0143 { 0144 init(); 0145 } 0146 0147 InputTag::InputTag(KileInfo* ki, const QString &text, const QString &iconText, const QKeySequence &cut, const QObject *receiver, const char *slot, KActionCollection *parent, const QString& name, QWidget *wparent, uint options, 0148 const TagData& data, const QString &hint, const QString &alter) 0149 : Tag(text, iconText, cut, receiver, slot, parent, name,data), m_ki(ki), 0150 m_parent(wparent), m_options(options), m_hint(hint), m_alter(alter) 0151 { 0152 init(); 0153 } 0154 0155 InputTag::InputTag(KileInfo* ki, const QString &text, const QString &iconText, const QString& pix, const QKeySequence &cut, const QObject *receiver, const char *slot, KActionCollection *parent, const QString& name, QWidget *wparent, uint options, 0156 const TagData& data, const QString &hint, const QString &alter) 0157 : Tag(text, iconText, pix, cut,receiver, slot, parent, name,data), m_ki(ki), 0158 m_parent(wparent), m_options(options), m_hint(hint), m_alter(alter) 0159 { 0160 init(); 0161 } 0162 0163 InputTag::~InputTag() 0164 { 0165 } 0166 0167 void InputTag::init() 0168 { 0169 m_history.clear(); 0170 } 0171 0172 void InputTag::addToHistory(const QString& str) 0173 { 0174 if(!m_history.contains(str)) { 0175 m_history.prepend(str); 0176 } 0177 } 0178 0179 void InputTag::emitData() 0180 { 0181 KILE_DEBUG_MAIN << "InputTag::emitData() " << m_ki->getName(); 0182 0183 InputDialog *dlg = new InputDialog(m_data.text, m_options, m_history, m_hint, m_alter, m_ki, m_parent, "input_dialog"); 0184 if (dlg->exec()) { 0185 if((!dlg->tag().isEmpty()) && hasHistory()) { 0186 addToHistory(dlg->tag()); 0187 } 0188 0189 TagData td(m_data); 0190 0191 td.tagBegin.replace("%R",dlg->tag()); 0192 td.tagEnd.replace("%R",dlg->tag()); 0193 0194 QString alt = dlg->useAlternative() ? "*" : ""; 0195 td.tagBegin.replace("%A", alt); 0196 td.tagEnd.replace("%A", alt); 0197 0198 if(dlg->useLabel()) { 0199 td.tagEnd += dlg->label(); 0200 td.dy++; 0201 } 0202 0203 if(dlg->usedSelection()) { 0204 m_ki->clearSelection(); 0205 } 0206 0207 // if a filename was given for a \input- or \include-command, 0208 // the cursor is moved out of the braces 0209 if ( (m_options & (KileAction::ShowBrowseButton | KileAction::FromLabelList | KileAction::FromBibItemList)) && !dlg->tag().isEmpty() ) { 0210 td.dx += dlg->tag().length() + 1; 0211 } 0212 0213 // insert tag 0214 emit(triggered(td)); 0215 // refresh document structure and project tree when a file was inserted 0216 if(dlg->useAddProjectFile()) { 0217 m_ki->docManager()->projectAddFile(QFileInfo(m_ki->getCompileName()).absolutePath() + '/' + dlg->tag()); 0218 } 0219 } 0220 delete dlg; 0221 } 0222 0223 /* 0224 InputDialog 0225 */ 0226 InputDialog::InputDialog(const QString &caption, uint options, const QStringList& history, const QString& hint, const QString& alter, KileInfo *ki, QWidget *parent, const char *name) 0227 : QDialog (parent), m_ki(ki) 0228 { 0229 setModal(true); 0230 0231 QVBoxLayout *mainLayout = new QVBoxLayout; 0232 setLayout(mainLayout); 0233 setObjectName(name); 0234 0235 QString newcaption = caption; 0236 setWindowTitle(newcaption.remove('&')); 0237 0238 m_labelprefix = (newcaption == "chapter") ? "chap:" : "sec:"; 0239 m_usedSelection = false; 0240 0241 QGridLayout *gbox = new QGridLayout(this); 0242 QWidget *page = new QWidget(this); 0243 page->setLayout(gbox); 0244 mainLayout->addWidget(page); 0245 0246 QLabel *lb = new QLabel(hint, this); 0247 gbox->addWidget(lb, 0, 0, 1, 3); 0248 0249 m_tag.clear(); 0250 QWidget *focus; 0251 if((options & KileAction::KeepHistory) || (options & KileAction::FromLabelList) || (options & KileAction::FromBibItemList)) { 0252 KComboBox *input = new KComboBox(true, this); 0253 input->setObjectName("input_dialog_input"); 0254 input->setCompletionMode(KCompletion::CompletionAuto); 0255 input->setMinimumWidth(300); 0256 focus = input; 0257 0258 connect(input, SIGNAL(textChanged(QString)), this, SLOT(setTag(QString))); 0259 connect(this, SIGNAL(setInput(QString)), input, SLOT(setEditText(QString))); 0260 if(options & KileAction::ShowBrowseButton) { 0261 gbox->addWidget(input, 1, 0); 0262 } 0263 else { 0264 gbox->addWidget(input, 1, 0, 1, 3); 0265 } 0266 0267 QStringList list; 0268 0269 if(options & KileAction::FromLabelList) { 0270 list = ki->allLabels(); 0271 if(list.size() > 0) { 0272 input->addItems(list); 0273 m_tag = list.first(); 0274 } 0275 } 0276 else if(options & KileAction::FromBibItemList) { 0277 list = ki->allBibItems(); 0278 if(list.size() > 0) { 0279 input->addItems(list); 0280 m_tag = list.first(); 0281 } 0282 } 0283 else { 0284 if(history.size() > 0) { 0285 input->addItems(history); 0286 m_tag = history.first(); 0287 } 0288 } 0289 } 0290 else { 0291 QLineEdit *input = new QLineEdit(this); 0292 gbox->addWidget(input); 0293 input->setMinimumWidth(300); 0294 focus = input; 0295 0296 connect(input, SIGNAL(textChanged(QString)), this, SLOT(setTag(QString))); 0297 connect(this, SIGNAL(setInput(QString)), input, SLOT(setText(QString))); 0298 if(options & KileAction::ShowBrowseButton) { 0299 gbox->addWidget(input, 1, 0); 0300 } 0301 else { 0302 gbox->addWidget(input, 1, 0, 1, 3); 0303 } 0304 0305 input->setText(ki->getSelection()); 0306 m_usedSelection=true; 0307 } 0308 0309 if(focus) { 0310 lb->setBuddy(focus); 0311 } 0312 0313 if(options & KileAction::ShowBrowseButton) { 0314 QPushButton *pbutton = new QPushButton(QString(), this); 0315 mainLayout->addWidget(pbutton); 0316 pbutton->setIcon(QIcon::fromTheme("document-open")); 0317 gbox->addWidget(pbutton, 1, 2); 0318 gbox->setColumnMinimumWidth(1, 8); 0319 gbox->setColumnMinimumWidth(2, pbutton->sizeHint().width() + 5); 0320 connect(pbutton, SIGNAL(clicked()), this, SLOT(slotBrowse())); 0321 } 0322 0323 if(options & KileAction::ShowAlternative) { 0324 QCheckBox *m_checkbox = new QCheckBox(alter, this); 0325 mainLayout->addWidget(m_checkbox); 0326 m_checkbox->setObjectName("input_dialog_checkbox"); 0327 connect(m_checkbox, SIGNAL(clicked()), this, SLOT(slotAltClicked())); 0328 m_useAlternative=false; 0329 gbox->addWidget(m_checkbox, 2, 0, 1, 3); 0330 } 0331 0332 m_edLabel = Q_NULLPTR; 0333 m_useLabel = (options & KileAction::ShowLabel); 0334 if(m_useLabel) { 0335 // Label 0336 QLabel *uiLabel = new QLabel(i18n("&Label:"),this); 0337 mainLayout->addWidget(uiLabel); 0338 m_edLabel = new QLineEdit(this); 0339 mainLayout->addWidget(m_edLabel); 0340 m_edLabel->setMinimumWidth(300); 0341 m_edLabel->setText(m_labelprefix); 0342 uiLabel->setBuddy(m_edLabel); 0343 gbox->addWidget(uiLabel, 3, 0, 1, 3); 0344 gbox->addWidget(m_edLabel, 4, 0, 1, 3); 0345 } 0346 0347 m_useAddProjectFile = (options & KileAction::AddProjectFile); 0348 0349 gbox->setRowStretch(5, 1); 0350 gbox->setColumnStretch(0, 1); 0351 0352 // add buttons 0353 QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel); 0354 mainLayout->addWidget(buttonBox); 0355 QPushButton *okButton = buttonBox->button(QDialogButtonBox::Ok); 0356 okButton->setDefault(true); 0357 okButton->setShortcut(Qt::CTRL | Qt::Key_Return); 0358 connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept())); 0359 connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); 0360 0361 focus->setFocus(); 0362 } 0363 0364 0365 InputDialog::~InputDialog() 0366 { 0367 } 0368 0369 void InputDialog::slotBrowse() 0370 { 0371 QString fn; 0372 QFileInfo fi(m_ki->getCompileName()); 0373 0374 // Called from InputDialog after a \input- or \include command: 0375 // so we are only looking for a LaTeX source document 0376 QString filter = m_ki->extensions()->fileFilterQtStyle(true, {KileDocument::Extensions::TEX}); 0377 0378 fn = QFileDialog::getOpenFileName(this, i18n("Select File"), fi.absoluteFilePath(), filter); 0379 if(!fn.isEmpty()) { 0380 QString path = QDir(fi.path()).relativeFilePath(fn); 0381 0382 // if the file has no extension, we add the default TeX extension 0383 if(QFileInfo(path).completeSuffix().isEmpty()) { 0384 path += m_ki->extensions()->latexDocumentDefault(); 0385 } 0386 0387 setTag(path); 0388 emit(setInput(path)); 0389 } 0390 } 0391 0392 void InputDialog::slotAltClicked() 0393 { 0394 m_useAlternative = !m_useAlternative; 0395 } 0396 0397 void InputDialog::setTag(const QString &tag) 0398 { 0399 m_tag = tag; 0400 } 0401 0402 QString InputDialog::label() 0403 { 0404 if(m_edLabel) { 0405 QString labelString = m_edLabel->text().trimmed(); 0406 if(!labelString.isEmpty() && labelString != m_labelprefix) { 0407 return "\\label{" + labelString + "}\n"; 0408 } 0409 } 0410 0411 return QString(); 0412 } 0413 0414 ///////////////// 0415 // SelectTag // 0416 ///////////////// 0417 0418 Select::Select(const QString &text, const QKeySequence &shortcut, KActionCollection *parent, const char *name) 0419 : KSelectAction(text, parent) 0420 { 0421 parent->addAction(name, this); 0422 parent->setDefaultShortcut(this, shortcut); 0423 } 0424 0425 void Select::setItems(const QList<QAction *>& list) 0426 { 0427 removeAllActions(); 0428 0429 for(QList<QAction *>::const_iterator i = list.begin(); i != list.end(); ++i) { 0430 addAction(*i); 0431 } 0432 } 0433 0434 ///////////////////////// 0435 // VariantSelection // 0436 ///////////////////////// 0437 0438 VariantSelection::VariantSelection(const QString &text, const QVariant& value, QObject *parent) 0439 : QAction(text, parent), m_variant(value) 0440 { 0441 connect(this, SIGNAL(triggered(bool)), this, SLOT(slotTriggered())); 0442 } 0443 0444 void VariantSelection::slotTriggered() 0445 { 0446 emit(triggered(m_variant)); 0447 0448 if(m_variant.canConvert<QUrl>()) { 0449 emit(triggered(m_variant.value<QUrl>())); 0450 } 0451 0452 if(m_variant.canConvert<QString>()) { 0453 emit(triggered(m_variant.value<QString>())); 0454 } 0455 } 0456 0457 } 0458 0459 // ToolbarSelectAction 0460 // based on 'KActionMenu', therefore our thanks go to 0461 // Copyright (C) 1999 Reginald Stadlbauer <reggie@kde.org> 0462 // (C) 1999 Simon Hausmann <hausmann@kde.org> 0463 // (C) 2000 Nicolas Hadacek <haadcek@kde.org> 0464 // (C) 2000 Kurt Granroth <granroth@kde.org> 0465 // (C) 2000 Michael Koch <koch@kde.org> 0466 // (C) 2001 Holger Freyther <freyther@kde.org> 0467 // (C) 2002 Ellis Whitehead <ellis@kde.org> 0468 // (C) 2002 Joseph Wenninger <jowenn@kde.org> 0469 // (C) 2003 Andras Mantia <amantia@kde.org> 0470 // (C) 2005-2006 Hamish Rodda <rodda@kde.org> 0471 0472 ToolbarSelectAction::ToolbarSelectAction(const QString& text, QObject* parent, 0473 bool changeMainActionOnTriggering /*= true */) 0474 : QWidgetAction(parent), m_currentItem(-1), m_mainText(text), m_savedCurrentAction(Q_NULLPTR) 0475 { 0476 setText(text); 0477 if(changeMainActionOnTriggering) { 0478 connect(menu(), SIGNAL(triggered(QAction*)), this, SLOT(slotTriggered(QAction*))); 0479 } 0480 } 0481 0482 int ToolbarSelectAction::actionIndex(QAction *action) 0483 { 0484 int counter = -1; 0485 QList<QAction*> actionList = menu()->actions(); 0486 for(QList<QAction*>::iterator i = actionList.begin(); i != actionList.end(); ++i) { 0487 if(*i == action) { 0488 return counter + 1; 0489 } 0490 ++counter; 0491 } 0492 return counter; 0493 } 0494 0495 void ToolbarSelectAction::addAction(QAction *action) 0496 { 0497 menu()->addAction(action); 0498 } 0499 0500 void ToolbarSelectAction::addSeparator() 0501 { 0502 menu()->addSeparator(); 0503 } 0504 0505 QAction* ToolbarSelectAction::action(int i) 0506 { 0507 QList<QAction*> actionList = menu()->actions(); 0508 if(i < 0 || i >= actionList.size()) { 0509 return Q_NULLPTR; 0510 } 0511 return actionList.at(i); 0512 } 0513 0514 int ToolbarSelectAction::currentItem() const 0515 { 0516 return m_currentItem; 0517 } 0518 0519 QAction* ToolbarSelectAction::currentAction() 0520 { 0521 return action(m_currentItem); 0522 } 0523 0524 bool ToolbarSelectAction::containsAction(QAction *action) 0525 { 0526 return actionIndex(action) >= 0; 0527 } 0528 0529 void ToolbarSelectAction::setCurrentItem(int i) 0530 { 0531 setCurrentAction(action(i)); 0532 } 0533 0534 void ToolbarSelectAction::setCurrentAction(QAction *action) 0535 { 0536 if(!action) { 0537 return; 0538 } 0539 int index = actionIndex(action); 0540 if(index < 0) { 0541 return; 0542 } 0543 setIcon(action->icon()); 0544 setText(action->text()); 0545 m_currentItem = index; 0546 } 0547 0548 void ToolbarSelectAction::removeAllActions() 0549 { 0550 menu()->clear(); 0551 m_currentItem = -1; 0552 setText(m_mainText); 0553 setIcon(QIcon()); 0554 } 0555 0556 void ToolbarSelectAction::slotTriggered(QAction* action) { 0557 0558 KILE_DEBUG_MAIN << "triggered with " << action->text(); 0559 0560 if( currentAction() != action ) { 0561 setIcon(action->icon()); 0562 setText(action->text()); 0563 setCurrentAction(action); 0564 } 0565 } 0566 0567 void ToolbarSelectAction::slotMainActionTriggered() 0568 { 0569 QAction *curAction = currentAction(); 0570 if (curAction) { 0571 curAction->trigger(); 0572 } 0573 } 0574 0575 void ToolbarSelectAction::slotMainButtonPressed() 0576 { 0577 QAction *curAction = currentAction(); 0578 if (!curAction) { 0579 emit(mainButtonWithNoActionPressed()); 0580 } 0581 } 0582 0583 QMenu* ToolbarSelectAction::menu() 0584 { 0585 if(!QAction::menu()) { 0586 QMenu *uiMenu = new QMenu(); 0587 setMenu(uiMenu); 0588 } 0589 0590 return qobject_cast<QMenu*>(QAction::menu()); 0591 } 0592 0593 QWidget* ToolbarSelectAction::createWidget(QWidget *parent) 0594 { 0595 QToolBar *parentToolBar = qobject_cast<QToolBar*>(parent); 0596 if (!parentToolBar) { 0597 return QWidgetAction::createWidget(parent); 0598 } 0599 QToolButton* button = new QToolButton(parent); 0600 button->setAutoRaise(true); 0601 button->setFocusPolicy(Qt::NoFocus); 0602 button->setPopupMode(QToolButton::MenuButtonPopup); 0603 button->setIconSize(parentToolBar->iconSize()); 0604 button->setToolButtonStyle(parentToolBar->toolButtonStyle()); 0605 connect(parent, SIGNAL(iconSizeChanged(QSize)), 0606 button, SLOT(setIconSize(QSize))); 0607 connect(parent, SIGNAL(toolButtonStyleChanged(Qt::ToolButtonStyle)), 0608 button, SLOT(setToolButtonStyle(Qt::ToolButtonStyle))); 0609 button->setDefaultAction(this); 0610 connect(button, SIGNAL(clicked(bool)), this, SLOT(slotMainActionTriggered())); 0611 connect(button, SIGNAL(pressed()), this, SLOT(slotMainButtonPressed())); 0612 connect(this, SIGNAL(mainButtonWithNoActionPressed()), button, SLOT(showMenu())); 0613 return button; 0614 } 0615 0616 void ToolbarSelectAction::saveCurrentAction() 0617 { 0618 m_savedCurrentAction = currentAction(); 0619 } 0620 0621 void ToolbarSelectAction::restoreCurrentAction() 0622 { 0623 if(!m_savedCurrentAction) { 0624 return; 0625 } 0626 setCurrentAction(m_savedCurrentAction); 0627 m_savedCurrentAction = Q_NULLPTR; 0628 } 0629