File indexing completed on 2024-05-12 16:34:58
0001 /* This file is part of the KDE project 0002 * Copyright (C) 2011 C. Boemann <cbo@boemann.dk> 0003 * Copyright (C) 2013 Aman Madaan <madaan.amanmadaan@gmail.com> 0004 * 0005 * This library is free software; you can redistribute it and/or 0006 * modify it under the terms of the GNU Library General Public 0007 * License as published by the Free Software Foundation; either 0008 * version 2 of the License, or (at your option) any later version. 0009 * 0010 * This library is distributed in the hope that it will be useful, 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0013 * Library General Public License for more details. 0014 * 0015 * You should have received a copy of the GNU Library General Public License 0016 * along with this library; see the file COPYING.LIB. If not, write to 0017 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0018 * Boston, MA 02110-1301, USA. 0019 */ 0020 0021 #include "ReferencesTool.h" 0022 #include "TextShape.h" 0023 #include "dialogs/SimpleTableOfContentsWidget.h" 0024 #include "dialogs/SimpleCitationBibliographyWidget.h" 0025 #include "dialogs/SimpleFootEndNotesWidget.h" 0026 #include "dialogs/SimpleCaptionsWidget.h" 0027 #include "dialogs/SimpleLinksWidget.h" 0028 #include "dialogs/TableOfContentsConfigure.h" 0029 #include "dialogs/NotesConfigurationDialog.h" 0030 #include "dialogs/CitationInsertionDialog.h" 0031 #include "dialogs/InsertBibliographyDialog.h" 0032 #include "dialogs/BibliographyConfigureDialog.h" 0033 #include "dialogs/LinkInsertionDialog.h" 0034 0035 #include <KoTextLayoutRootArea.h> 0036 #include <KoCanvasBase.h> 0037 #include <KoTextEditor.h> 0038 #include <KoParagraphStyle.h> 0039 #include <KoTableOfContentsGeneratorInfo.h> 0040 #include <KoBookmark.h> 0041 #include <KoInlineNote.h> 0042 #include <KoTextDocumentLayout.h> 0043 #include <KoIcon.h> 0044 #include <QMessageBox> 0045 0046 #include <QDebug> 0047 #include <QAction> 0048 #include <QTextDocument> 0049 #include <QLineEdit> 0050 #include <QBoxLayout> 0051 #include <QMenu> 0052 #include <QWidgetAction> 0053 0054 LabeledWidget::LabeledWidget(QAction *action, const QString &label, LabelPosition lb, bool warningLabelRequired) 0055 : QWidget() 0056 , m_action(action) 0057 { 0058 setMouseTracking(true); 0059 QBoxLayout *layout; 0060 QLabel *l = new QLabel(label); 0061 l->setWordWrap(true); 0062 m_lineEdit = new QLineEdit(); 0063 if (lb == LabeledWidget::INLINE) { // label followed by line edit 0064 layout = new QHBoxLayout(); 0065 l->setIndent(l->style()->pixelMetric(QStyle::PM_SmallIconSize) 0066 + l->style()->pixelMetric(QStyle::PM_MenuPanelWidth) + 4); 0067 } else { //Label goes above the text edit 0068 layout = new QVBoxLayout(); 0069 m_lineEdit->setFixedWidth(300); //TODO : assuming a reasonable width, is there a better way? 0070 } 0071 layout->addWidget(l); 0072 layout->addWidget(m_lineEdit); 0073 if (warningLabelRequired) { 0074 m_warningLabel[0] = new QLabel(""); 0075 m_warningLabel[1] = new QLabel(""); 0076 m_warningLabel[0]->setWordWrap(true); 0077 m_warningLabel[1]->setWordWrap(true); 0078 layout->addWidget(m_warningLabel[0]); 0079 layout->addWidget(m_warningLabel[1]); 0080 } 0081 layout->setMargin(0); 0082 setLayout(layout); 0083 connect(m_lineEdit, SIGNAL(returnPressed()), this, SLOT(returnPressed())); 0084 connect(m_lineEdit, SIGNAL(textChanged(QString)), this, SIGNAL(lineEditChanged(QString))); 0085 } 0086 0087 void LabeledWidget::returnPressed() 0088 { 0089 emit triggered(m_lineEdit->text()); 0090 } 0091 0092 void LabeledWidget::enterEvent(QEvent *event) 0093 { 0094 m_action->activate(QAction::Hover); 0095 QWidget::enterEvent(event); 0096 } 0097 0098 void LabeledWidget::setWarningText(int pos, const QString& warning) 0099 { 0100 if (m_warningLabel[pos] == nullptr) { 0101 return; 0102 } 0103 m_warningLabel[pos]->setText(warning); 0104 } 0105 0106 void LabeledWidget::clearLineEdit() 0107 { 0108 m_lineEdit->setText(""); 0109 } 0110 0111 ReferencesTool::ReferencesTool(KoCanvasBase* canvas): TextTool(canvas), 0112 m_configure(0), 0113 m_stocw(0), 0114 m_canvas(canvas) 0115 { 0116 createActions(); 0117 } 0118 0119 ReferencesTool::~ReferencesTool() 0120 { 0121 } 0122 0123 void ReferencesTool::createActions() 0124 { 0125 QWidgetAction *wAction = 0; 0126 0127 QAction *action = new QAction(i18n("Insert"), this); 0128 addAction("insert_tableofcontents", action); 0129 action->setToolTip(i18n("Insert a Table of Contents into the document.")); 0130 0131 action = new QAction(i18n("Insert Custom..."), this); 0132 addAction("insert_configure_tableofcontents", action); 0133 action->setToolTip(i18n("Insert a custom Table of Contents into the document.")); 0134 0135 action = new QAction(koIcon("configure"), i18n("Configure..."), this); 0136 addAction("format_tableofcontents", action); 0137 action->setToolTip(i18n("Configure the Table of Contents")); 0138 connect(action, SIGNAL(triggered()), this, SLOT(formatTableOfContents())); 0139 0140 action = new QAction(i18n("Insert footnote with auto number"),this); 0141 addAction("insert_autofootnote",action); 0142 connect(action, SIGNAL(triggered()), this, SLOT(insertAutoFootNote())); 0143 0144 wAction = new QWidgetAction(this); 0145 wAction->setText(i18n("Insert Labeled Footnote")); 0146 QWidget *w = new LabeledWidget(wAction, i18n("Insert with label:"), LabeledWidget::INLINE, false); 0147 wAction->setDefaultWidget(w); 0148 addAction("insert_labeledfootnote", wAction); 0149 connect(w, SIGNAL(triggered(QString)), this, SLOT(insertLabeledFootNote(QString))); 0150 0151 action = new QAction(i18n("Insert endnote with auto number"),this); 0152 addAction("insert_autoendnote",action); 0153 connect(action, SIGNAL(triggered()), this, SLOT(insertAutoEndNote())); 0154 0155 wAction = new QWidgetAction(this); 0156 wAction->setText(i18n("Insert Labeled Endnote")); 0157 w = new LabeledWidget(wAction, i18n("Insert with label:"), LabeledWidget::INLINE, false); 0158 wAction->setDefaultWidget(w); 0159 addAction("insert_labeledendnote", wAction); connect(w, SIGNAL(triggered(QString)), this, SLOT(insertLabeledEndNote(QString))); 0160 0161 action = new QAction(koIcon("configure"), i18n("Settings..."), this); 0162 addAction("format_footnotes",action); 0163 connect(action, SIGNAL(triggered()), this, SLOT(showFootnotesConfigureDialog())); 0164 0165 action = new QAction(koIcon("configure"), i18n("Settings..."), this); 0166 addAction("format_endnotes",action); 0167 connect(action, SIGNAL(triggered()), this, SLOT(showEndnotesConfigureDialog())); 0168 0169 action = new QAction(i18n("Insert Citation"), this); 0170 addAction("insert_citation",action); 0171 action->setToolTip(i18n("Insert a citation into the document.")); 0172 connect(action, SIGNAL(triggered()), this, SLOT(insertCitation())); 0173 0174 action = new QAction(i18n("Insert Bibliography"), this); 0175 addAction("insert_bibliography",action); 0176 action->setToolTip(i18n("Insert a bibliography into the document.")); 0177 0178 action = new QAction(i18n("Insert Custom Bibliography"), this); 0179 addAction("insert_custom_bibliography", action); 0180 action->setToolTip(i18n("Insert a custom Bibliography into the document.")); 0181 0182 action = new QAction(i18n("Configure"),this); 0183 addAction("configure_bibliography",action); 0184 action->setToolTip(i18n("Configure the bibliography")); 0185 connect(action, SIGNAL(triggered()), this, SLOT(configureBibliography())); 0186 0187 action = new QAction(i18n("Insert Link"), this); 0188 addAction("insert_link", action); 0189 action->setToolTip(i18n("Insert a weblink or link to a bookmark.")); 0190 connect(action, SIGNAL(triggered()), this, SLOT(insertLink())); 0191 0192 wAction = new QWidgetAction(this); 0193 wAction->setText(i18n("Add Bookmark")); 0194 m_bmark = new LabeledWidget(wAction, i18n("Add Bookmark :"), LabeledWidget::ABOVE, true); 0195 connect(m_bmark, SIGNAL(lineEditChanged(QString)), this, SLOT(validateBookmark(QString))); 0196 wAction->setDefaultWidget(m_bmark); 0197 addAction("insert_bookmark", wAction); 0198 connect(m_bmark, SIGNAL(triggered(QString)), this, SLOT(insertBookmark(QString))); 0199 wAction->setToolTip(i18n("Insert a Bookmark. This is useful to create links that point to areas within the document")); 0200 0201 action = new QAction(i18n("Bookmarks"), this); 0202 addAction("invoke_bookmark_handler", action); 0203 action->setToolTip(i18n("Display a pop up that hosts the options to add new Bookmark or handle existing Bookmarks")); 0204 0205 action = new QAction(i18n("Manage Bookmarks"), this); 0206 addAction("manage_bookmarks", action); 0207 action->setToolTip(i18n("Manage your Bookmarks. Check where are they pointing to, Delete or Rename.")); 0208 } 0209 0210 0211 void ReferencesTool::activate(ToolActivation toolActivation, const QSet<KoShape*> &shapes) 0212 { 0213 TextTool::activate(toolActivation, shapes); 0214 } 0215 0216 void ReferencesTool::deactivate() 0217 { 0218 TextTool::deactivate(); 0219 canvas()->canvasWidget()->setFocus(); 0220 } 0221 0222 QList<QPointer<QWidget> > ReferencesTool::createOptionWidgets() 0223 { 0224 QList<QPointer<QWidget> > widgets; 0225 m_stocw = new SimpleTableOfContentsWidget(this, 0); 0226 0227 m_sfenw = new SimpleFootEndNotesWidget(this, 0); 0228 0229 m_scbw = new SimpleCitationBibliographyWidget(this, 0); 0230 0231 m_slw = new SimpleLinksWidget(this, 0); 0232 // Connect to/with simple table of contents option widget 0233 connect(m_stocw, SIGNAL(doneWithFocus()), this, SLOT(returnFocusToCanvas())); 0234 0235 // Connect to/with simple citation index option widget 0236 //connect(scw, SIGNAL(doneWithFocus()), this, SLOT(returnFocusToCanvas())); 0237 0238 // Connect to/with simple citation index option widget 0239 connect(m_sfenw, SIGNAL(doneWithFocus()), this, SLOT(returnFocusToCanvas())); 0240 0241 connect(m_slw, SIGNAL(doneWithFocus()), this, SLOT(returnFocusToCanvas())); 0242 0243 m_stocw->setWindowTitle(i18nc("as in table of contents, list of pictures, index", "Tables, Lists & Indexes")); 0244 widgets.append(m_stocw); 0245 0246 m_sfenw->setWindowTitle(i18n("Footnotes and Endnotes")); 0247 widgets.append(m_sfenw); 0248 0249 m_scbw->setWindowTitle(i18n("Citations and Bibliography")); 0250 widgets.append(m_scbw); 0251 0252 m_slw->setWindowTitle(i18n("Links and Bookmarks")); 0253 widgets.append(m_slw); 0254 //widgets.insert(i18n("Captions"), scapw); 0255 connect(textEditor(), SIGNAL(cursorPositionChanged()), this, SLOT(updateButtons())); 0256 return widgets; 0257 } 0258 0259 void ReferencesTool::insertCitation() 0260 { 0261 new CitationInsertionDialog(textEditor(), m_scbw); 0262 } 0263 0264 void ReferencesTool::insertCustomBibliography(KoBibliographyInfo *defaultTemplate) 0265 { 0266 Q_UNUSED(defaultTemplate); 0267 new InsertBibliographyDialog(textEditor(), m_scbw); 0268 } 0269 0270 void ReferencesTool::configureBibliography() 0271 { 0272 new BibliographyConfigureDialog(textEditor()->document(), m_scbw); 0273 } 0274 0275 void ReferencesTool::formatTableOfContents() 0276 { 0277 if (textEditor()->block().blockFormat().hasProperty(KoParagraphStyle::TableOfContentsData)) { 0278 m_configure = new TableOfContentsConfigure(textEditor(), textEditor()->block(), m_stocw); 0279 connect(m_configure, SIGNAL(finished(int)), this, SLOT(hideCofigureDialog())); 0280 } 0281 } 0282 0283 void ReferencesTool::showConfigureDialog(QAction *action) 0284 { 0285 m_configure = new TableOfContentsConfigure(textEditor(), action->data().value<QTextBlock>(), m_stocw); 0286 connect(m_configure, SIGNAL(finished(int)), this, SLOT(hideCofigureDialog())); 0287 } 0288 0289 void ReferencesTool::hideCofigureDialog() 0290 { 0291 disconnect(m_configure, SIGNAL(finished(int)), this, SLOT(hideCofigureDialog())); 0292 m_configure->deleteLater(); 0293 } 0294 0295 void ReferencesTool::insertAutoFootNote() 0296 { 0297 m_note = textEditor()->insertFootNote(); 0298 m_note->setAutoNumbering(true); 0299 } 0300 0301 void ReferencesTool::insertLabeledFootNote(const QString &label) 0302 { 0303 m_note = textEditor()->insertFootNote(); 0304 m_note->setAutoNumbering(false); 0305 m_note->setLabel(label); 0306 } 0307 0308 void ReferencesTool::insertAutoEndNote() 0309 { 0310 m_note = textEditor()->insertEndNote(); 0311 m_note->setAutoNumbering(true); 0312 } 0313 0314 void ReferencesTool::insertLabeledEndNote(const QString &label) 0315 { 0316 m_note = textEditor()->insertEndNote(); 0317 m_note->setAutoNumbering(false); 0318 m_note->setLabel(label); 0319 } 0320 0321 void ReferencesTool::showFootnotesConfigureDialog() 0322 { 0323 NotesConfigurationDialog *dialog = new NotesConfigurationDialog((QTextDocument *)textEditor()->document(), true); 0324 dialog->exec(); 0325 } 0326 0327 void ReferencesTool::showEndnotesConfigureDialog() 0328 { 0329 NotesConfigurationDialog *dialog = new NotesConfigurationDialog((QTextDocument *)textEditor()->document(), false); 0330 dialog->exec(); 0331 } 0332 0333 void ReferencesTool::updateButtons() 0334 { 0335 if (textEditor()->currentFrame()->format().intProperty(KoText::SubFrameType) == KoText::NoteFrameType) { 0336 m_sfenw->widget.addFootnote->setEnabled(false); 0337 m_sfenw->widget.addEndnote->setEnabled(false); 0338 } else { 0339 m_sfenw->widget.addFootnote->setEnabled(true); 0340 m_sfenw->widget.addEndnote->setEnabled(true); 0341 } 0342 if (textEditor()->block().blockFormat().hasProperty(KoParagraphStyle::TableOfContentsData)) { 0343 action("format_tableofcontents")->setEnabled(true); 0344 } else { 0345 action("format_tableofcontents")->setEnabled(false); 0346 } 0347 0348 } 0349 0350 KoTextEditor *ReferencesTool::editor() 0351 { 0352 return textEditor(); 0353 } 0354 0355 void ReferencesTool::insertCustomToC(KoTableOfContentsGeneratorInfo *defaultTemplate) 0356 { 0357 m_configure = new TableOfContentsConfigure(textEditor(), defaultTemplate, m_stocw); 0358 connect(m_configure, SIGNAL(accepted()), this, SLOT(customToCGenerated())); 0359 connect(m_configure, SIGNAL(finished(int)), this, SLOT(hideCofigureDialog())); 0360 } 0361 0362 void ReferencesTool::customToCGenerated() 0363 { 0364 if (m_configure) { 0365 textEditor()->insertTableOfContents(m_configure->currentToCData()); 0366 } 0367 } 0368 0369 void ReferencesTool::insertLink() 0370 { 0371 new LinkInsertionDialog(textEditor(), m_slw); 0372 } 0373 0374 bool ReferencesTool::validateBookmark(QString bookmarkName) 0375 { 0376 bookmarkName = bookmarkName.trimmed(); 0377 if (bookmarkName.isEmpty()) { 0378 m_bmark->setWarningText(0, i18n("Bookmark cannot be empty")); 0379 return false; 0380 } 0381 const KoBookmarkManager *manager = KoTextDocument(editor()->document()).textRangeManager()->bookmarkManager(); 0382 QStringList existingBookmarks = manager->bookmarkNameList(); 0383 int position = existingBookmarks.indexOf(bookmarkName); 0384 if (position != -1) { 0385 m_bmark->setWarningText(0, i18n("Duplicate Name. Click \"Manage Bookmarks\"")); 0386 m_bmark->setWarningText(1, i18n("to Rename or Delete Bookmarks")); 0387 return false; 0388 } else { 0389 m_bmark->setWarningText(0, ""); 0390 m_bmark->setWarningText(1, ""); 0391 return true; 0392 } 0393 } 0394 0395 void ReferencesTool::insertBookmark(QString bookMarkName) 0396 { 0397 bookMarkName = bookMarkName.trimmed(); 0398 m_bmark->setWarningText(0, ""); 0399 m_bmark->setWarningText(1, ""); 0400 if (validateBookmark(bookMarkName)) { 0401 editor()->addBookmark(bookMarkName); 0402 m_bmark->clearLineEdit(); 0403 } 0404 }