Commit 2f4dd4ff authored by Aman Madaan's avatar Aman Madaan

Expansion of the References section by adding features to insert hyperlinks,

bookmarks and links to bookmarks.

This patch adds the following features :

1. Inserting hyperlinks

   -- User has a choice of inserting a link by specifying the target and the
link text.
   -- The user may fetch the title from the web page itself (contents of the
"title" tag ). This feature also handles URL redirects.This feature will especially
help in cases when a user has a list of links referred to and a list of references
has to be created. Just copy/pasting the URL, clicking fetch and then insert will do the job.

2. Linking to bookmarks

   -- A user can specify a bookmark name and the link text. To help the user
with inserting a bookmark, an auto completer is used.

3. Adding Bookmark using a labeled widget ( similar to the way footnote and
endnote labels are entered)

4. Improvement to the Manage Bookmarks ui by adding feature to insert a bookmark
and fixing bugs.

A list of commit headlines follow :

    Added licenses
    Fixed Insert and Rename feature in ManageBookmarks.
    Deleted Advanced options.
    Combined bookmark name line edit and the list widget into an editable combobox.
    Finised Internationalization
    Modify insertText() to accomodate links
    Merged LinkedInsertionDialog, WeblinkInsertionWidget and
    Add a new bookmark to the list as it is added
    Simple Link insertion finished.
    Added the SimpleLinkWidget to the references dock
    sg
parent a8381c20
......@@ -1412,7 +1412,7 @@ KoInlineCite *KoTextEditor::insertCitation()
return cite;
}
void KoTextEditor::insertText(const QString &text)
void KoTextEditor::insertText(const QString &text, const QString &hRef)
{
if (isEditProtected()) {
return;
......@@ -1442,7 +1442,18 @@ void KoTextEditor::insertText(const QString &text)
if (format.hasProperty(KoCharacterStyle::ChangeTrackerId)) {
format.clearProperty(KoCharacterStyle::ChangeTrackerId);
}
static QRegExp urlScanner("\\S+://\\S+");
if (!hRef.isEmpty()) {
format.setAnchor(true);
format.setProperty(KoCharacterStyle::AnchorType, KoCharacterStyle::Anchor);
if ((urlScanner.indexIn(hRef)) == 0) {//web url
format.setAnchorHref(hRef);
} else {
format.setAnchorHref("#"+hRef);
}
}
d->caret.insertText(text, format);
int endPosition = d->caret.position();
//Mark the inserted text
......@@ -1457,7 +1468,12 @@ void KoTextEditor::insertText(const QString &text)
d->caret.endEditBlock();
endEditBlock();
}
if (!hRef.isEmpty()) {
format.setAnchor(false);
format.clearProperty(KoCharacterStyle::Anchor);
format.clearProperty(KoCharacterStyle::AnchorType);
d->caret.setCharFormat(format);
}
emit cursorPositionChanged();
}
......
......@@ -441,7 +441,15 @@ public slots:
KoInlineCite *insertCitation();
void insertText(const QString &text);
/**
* Inserts the supplied text at the current cursor position. If the second argument is
* supplied, a link is inserted at the current cursor position with the hRef as given
* by the user. To test whether the supplied link destination is a web url or a bookmark,
* a regular expression ( \\S+://\\S+ ) is used.
* @param text is the text to be inserted
* @param hRef if supplied is the Hypertext reference
*/
void insertText(const QString &text, const QString &hRef = QString());
void insertHtml(const QString &html);
......
......@@ -49,8 +49,10 @@ SET ( textshape_SRCS
dialogs/SimpleParagraphWidget.cpp
dialogs/SimpleTableWidget.cpp
dialogs/SimpleInsertWidget.cpp
dialogs/LinkInsertionDialog.cpp
dialogs/SimpleTableOfContentsWidget.cpp
dialogs/SimpleCitationBibliographyWidget.cpp
dialogs/SimpleLinksWidget.cpp
dialogs/SimpleSpellCheckingWidget.cpp
dialogs/CitationInsertionDialog.cpp
dialogs/InsertBibliographyDialog.cpp
......@@ -101,6 +103,7 @@ SET ( textshape_SRCS
dialogs/BibliographyTemplate.cpp
dialogs/BibliographyPreview.cpp
dialogs/ListLevelChooser.cpp
dialogs/ManageBookmarkDialog.cpp
commands/ChangeListLevelCommand.cpp
commands/ShowChangesCommand.cpp
......@@ -146,13 +149,16 @@ kde4_add_ui_files(textshape_SRCS
dialogs/TableDialog.ui
dialogs/BibliographyConfigureDialog.ui
dialogs/TableOfContentsConfigure.ui
dialogs/SimpleLinksWidget.ui
dialogs/TableOfContentsStyleConfigure.ui
dialogs/FontDecorations.ui
dialogs/LanguageTab.ui
dialogs/ChangeConfigureDialog.ui
dialogs/AcceptRejectChangeDialog.ui
dialogs/TrackedChangeManager.ui
dialogs/LinkInsertionDialog.ui
dialogs/ManageBookmark.ui
)
kde4_add_plugin(textshape ${textshape_SRCS})
......
/* This file is part of the KDE project
* Copyright (C) 2011 C. Boemann <cbo@boemann.dk>
* Copyright (C) 2013 Aman Madaan <madaan.amanmadaan@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
......@@ -23,11 +24,13 @@
#include "dialogs/SimpleCitationBibliographyWidget.h"
#include "dialogs/SimpleFootEndNotesWidget.h"
#include "dialogs/SimpleCaptionsWidget.h"
#include "dialogs/SimpleLinksWidget.h"
#include "dialogs/TableOfContentsConfigure.h"
#include "dialogs/NotesConfigurationDialog.h"
#include "dialogs/CitationInsertionDialog.h"
#include "dialogs/InsertBibliographyDialog.h"
#include "dialogs/BibliographyConfigureDialog.h"
#include "dialogs/LinkInsertionDialog.h"
#include <KoTextLayoutRootArea.h>
#include <KoCanvasBase.h>
......@@ -38,50 +41,77 @@
#include <KoInlineNote.h>
#include <KoTextDocumentLayout.h>
#include <KoIcon.h>
#include <QMessageBox>
#include <kdebug.h>
#include <klocale.h>
#include <kaction.h>
#include <KDebug>
#include <KLocale>
#include <KAction>
#include <QTextDocument>
#include <QLineEdit>
#include <QBoxLayout>
#include <QMenu>
LabeledNoteWidget::LabeledNoteWidget(KAction *action)
LabeledWidget::LabeledWidget(KAction *action, const QString label, LabelPosition lb, bool warningLabelRequired)
: QWidget()
, m_action(action)
{
setMouseTracking(true);
QHBoxLayout *layout = new QHBoxLayout();
QLabel *l = new QLabel(i18n("Insert with label:"));
l->setIndent(l->style()->pixelMetric(QStyle::PM_SmallIconSize)
+ l->style()->pixelMetric(QStyle::PM_MenuPanelWidth)
+ 4);
layout->addWidget(l);
QBoxLayout *layout;
QLabel *l = new QLabel(label);
l->setWordWrap(true);
m_lineEdit = new QLineEdit();
if (lb == LabeledWidget::INLINE) { // label followed by line edit
layout = new QHBoxLayout();
l->setIndent(l->style()->pixelMetric(QStyle::PM_SmallIconSize)
+ l->style()->pixelMetric(QStyle::PM_MenuPanelWidth) + 4);
} else { //Label goes above the text edit
layout = new QVBoxLayout();
m_lineEdit->setFixedWidth(300); //TODO : assuming a reasonable width, is there a better way?
}
layout->addWidget(l);
layout->addWidget(m_lineEdit);
if (warningLabelRequired) {
m_warningLabel[0] = new QLabel("");
m_warningLabel[1] = new QLabel("");
m_warningLabel[0]->setWordWrap(true);
m_warningLabel[1]->setWordWrap(true);
layout->addWidget(m_warningLabel[0]);
layout->addWidget(m_warningLabel[1]);
}
layout->setMargin(0);
setLayout(layout);
connect(m_lineEdit, SIGNAL(returnPressed()), this, SLOT(returnPressed()));
connect(m_lineEdit, SIGNAL(textChanged(QString)), this, SIGNAL(lineEditChanged(QString)));
}
void LabeledNoteWidget::returnPressed()
void LabeledWidget::returnPressed()
{
emit triggered(m_lineEdit->text());
}
void LabeledNoteWidget::enterEvent(QEvent *event)
void LabeledWidget::enterEvent(QEvent *event)
{
m_action->activate(QAction::Hover);
QWidget::enterEvent(event);
}
void LabeledWidget::setWarningText(int pos, const QString& warning)
{
if ((m_warningLabel[pos] == NULL)) {
return;
}
m_warningLabel[pos]->setText(warning);
}
void LabeledWidget::clearLineEdit()
{
m_lineEdit->setText("");
}
ReferencesTool::ReferencesTool(KoCanvasBase* canvas): TextTool(canvas),
m_configure(0),
m_stocw(0)
m_stocw(0),
m_canvas(canvas)
{
createActions();
}
......@@ -110,7 +140,7 @@ void ReferencesTool::createActions()
connect(action, SIGNAL(triggered()), this, SLOT(insertAutoFootNote()));
action = new KAction(i18n("Insert Labeled Footnote"), this);
QWidget *w = new LabeledNoteWidget(action);
QWidget *w = new LabeledWidget(action, i18n("Insert with label:"), LabeledWidget::INLINE, false);
action->setDefaultWidget(w);
addAction("insert_labeledfootnote", action);
connect(w, SIGNAL(triggered(QString)), this, SLOT(insertLabeledFootNote(QString)));
......@@ -120,7 +150,7 @@ void ReferencesTool::createActions()
connect(action, SIGNAL(triggered()), this, SLOT(insertAutoEndNote()));
action = new KAction(i18n("Insert Labeled Endnote"), this);
w = new LabeledNoteWidget(action);
w = new LabeledWidget(action, i18n("Insert with label:"), LabeledWidget::INLINE, false);
action->setDefaultWidget(w);
addAction("insert_labeledendnote", action);
connect(w, SIGNAL(triggered(QString)), this, SLOT(insertLabeledEndNote(QString)));
......@@ -133,24 +163,47 @@ void ReferencesTool::createActions()
addAction("format_endnotes",action);
connect(action, SIGNAL(triggered()), this, SLOT(showEndnotesConfigureDialog()));
action = new KAction(i18n("Insert Citation"),this);
action = new KAction(i18n("Insert Citation"), this);
addAction("insert_citation",action);
action->setToolTip(i18n("Insert a citation into the document."));
connect(action, SIGNAL(triggered()), this, SLOT(insertCitation()));
action = new KAction(i18n("Insert Bibliography"),this);
action = new KAction(i18n("Insert Bibliography"), this);
addAction("insert_bibliography",action);
action->setToolTip(i18n("Insert a bibliography into the document."));
action = new KAction(i18n("Insert Custom Bibliography"), this);
addAction("insert_custom_bibliography", action);
action->setToolTip(i18n("Insert a custom Bibliography into the document."));
action = new KAction(i18n("Configure"),this);
addAction("configure_bibliography",action);
action->setToolTip(i18n("Configure the bibliography"));
connect(action, SIGNAL(triggered()), this, SLOT(configureBibliography()));
action = new KAction(i18n("Insert Link"), this);
addAction("insert_link", action);
action->setToolTip(i18n("Insert a weblink or link to a bookmark."));
connect(action, SIGNAL(triggered()), this, SLOT(insertLink()));
action = new KAction(i18n("Add Bookmark"), this);
m_bmark = new LabeledWidget(action, i18n("Add Bookmark :"), LabeledWidget::ABOVE, true);
connect(m_bmark, SIGNAL(lineEditChanged(QString)), this, SLOT(validateBookmark(QString)));
action->setDefaultWidget(m_bmark);
addAction("insert_bookmark", action);
connect(m_bmark, SIGNAL(triggered(QString)), this, SLOT(insertBookmark(QString)));
action->setToolTip(i18n("Insert a Bookmark. This is useful to create links that point to areas within the document"));
action = new KAction(i18n("Bookmarks"), this);
addAction("invoke_bookmark_handler", action);
action->setToolTip(i18n("Display a pop up that hosts the options to add new Bookmark or handle existing Bookmarks"));
action = new KAction(i18n("Manage Bookmarks"), this);
addAction("manage_bookmarks", action);
action->setToolTip(i18n("Manage your Bookmarks. Check where are they pointing to, Delete or Rename."));
}
void ReferencesTool::activate(ToolActivation toolActivation, const QSet<KoShape*> &shapes)
{
TextTool::activate(toolActivation, shapes);
......@@ -167,9 +220,11 @@ QList<QWidget*> ReferencesTool::createOptionWidgets()
QList<QWidget *> widgets;
m_stocw = new SimpleTableOfContentsWidget(this, 0);
m_sfenw = new SimpleFootEndNotesWidget(this,0);
m_sfenw = new SimpleFootEndNotesWidget(this, 0);
m_scbw = new SimpleCitationBibliographyWidget(this, 0);
m_scbw = new SimpleCitationBibliographyWidget(this,0);
m_slw = new SimpleLinksWidget(this, 0);
// Connect to/with simple table of contents option widget
connect(m_stocw, SIGNAL(doneWithFocus()), this, SLOT(returnFocusToCanvas()));
......@@ -179,6 +234,8 @@ QList<QWidget*> ReferencesTool::createOptionWidgets()
// Connect to/with simple citation index option widget
connect(m_sfenw, SIGNAL(doneWithFocus()), this, SLOT(returnFocusToCanvas()));
connect(m_slw, SIGNAL(doneWithFocus()), this, SLOT(returnFocusToCanvas()));
m_stocw->setWindowTitle(i18n("Table of Contents"));
widgets.append(m_stocw);
......@@ -187,6 +244,9 @@ QList<QWidget*> ReferencesTool::createOptionWidgets()
m_scbw->setWindowTitle(i18n("Citations and Bibliography"));
widgets.append(m_scbw);
m_slw->setWindowTitle(i18n("Links and Bookmarks"));
widgets.append(m_slw);
//widgets.insert(i18n("Captions"), scapw);
connect(textEditor(), SIGNAL(cursorPositionChanged()), this, SLOT(updateButtons()));
return widgets;
......@@ -321,4 +381,41 @@ void ReferencesTool::customToCGenerated()
}
}
void ReferencesTool::insertLink()
{
new LinkInsertionDialog(textEditor(), m_slw);
}
bool ReferencesTool::validateBookmark(QString bookmarkName)
{
bookmarkName = bookmarkName.trimmed();
if (bookmarkName.isEmpty()) {
m_bmark->setWarningText(0, i18n("Bookmark cannot be empty"));
return false;
}
const KoBookmarkManager *manager = KoTextDocument(editor()->document()).textRangeManager()->bookmarkManager();
QStringList existingBookmarks = manager->bookmarkNameList();
int position = existingBookmarks.indexOf(bookmarkName);
if (position != -1) {
m_bmark->setWarningText(0, i18n("Duplicate Name. Click \"Manage Bookmarks\""));
m_bmark->setWarningText(1, i18n("to Rename or Delete Bookmarks"));
return false;
} else {
m_bmark->setWarningText(0, "");
m_bmark->setWarningText(1, "");
return true;
}
}
void ReferencesTool::insertBookmark(QString bookMarkName)
{
bookMarkName = bookMarkName.trimmed();
m_bmark->setWarningText(0, "");
m_bmark->setWarningText(1, "");
if (validateBookmark(bookMarkName)) {
editor()->addBookmark(bookMarkName);
m_bmark->clearLineEdit();
}
}
#include <ReferencesTool.moc>
/* This file is part of the KDE project
* Copyright (C) 2011 C. Boemann <cbo@boemann.dk>
* Copyright (C) 2013 Aman Madaan <madaan.amanmadaan@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
......@@ -21,6 +22,7 @@
#define REFERENCESTOOL_H
#include "TextTool.h"
#include <signal.h>
class KoCanvasBase;
class TableOfContentsConfigure;
......@@ -30,7 +32,8 @@ class SimpleCitationBibliographyWidget;
class KoInlineNote;
class KoTextEditor;
class QPainter;
class SimpleLinksWidget;
class LabeledWidget;
/// This tool is the ui for inserting Table of Contents, Citations/bibliography, footnotes, endnotes, index, table of illustrations etc
class ReferencesTool : public TextTool
......@@ -83,34 +86,48 @@ private slots:
void updateButtons();
void customToCGenerated();
/// insert a Link
void insertLink();
///insert a bookmark
void insertBookmark(QString bookmarkName);
/// validate a bookmark
bool validateBookmark(QString bookmarkName);
private:
TableOfContentsConfigure *m_configure;
SimpleTableOfContentsWidget *m_stocw;
SimpleFootEndNotesWidget *m_sfenw;
KoInlineNote *m_note;
SimpleFootEndNotesWidget *m_sfenw;
KoInlineNote *m_note;
SimpleCitationBibliographyWidget *m_scbw;
SimpleLinksWidget *m_slw;
LabeledWidget *m_bmark;
KoCanvasBase *m_canvas;
};
class KAction;
class QLineEdit;
class LabeledNoteWidget : public QWidget
class QLabel;
class LabeledWidget : public QWidget
{
Q_OBJECT
public:
explicit LabeledNoteWidget(KAction *action);
KAction *m_action;
QLineEdit *m_lineEdit;
enum LabelPosition {INLINE, ABOVE};
LabeledWidget(KAction *action, const QString label, LabelPosition pos, bool warningLabelRequired);
void setWarningText(int pos, const QString &warning);
void clearLineEdit();
signals:
void triggered(QString label);
void lineEditChanged(QString);
private slots:
void returnPressed();
protected:
virtual void enterEvent(QEvent *event);
private :
QLineEdit *m_lineEdit;
QLabel *m_warningLabel[2];
KAction *m_action;
};
#endif // REFERENCESTOOL_H
This diff is collapsed.
/* This file is part of the KDE project
* Copyright (C) 2013 Aman Madaan <madaan.amanmadaan@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef LINKINSERTDIALOG
#define LINKINSERTDIALOG
#include <ui_LinkInsertionDialog.h>
#include <QDialog>
#include <qnetworkreply.h>
#include <qnetworkaccessmanager.h>
#include <QWidget>
#include <KoBookmarkManager.h>
#include <KoTextRangeManager.h>
#include <KoTextDocument.h>
#include <QListWidget>
#define FETCH_TIMEOUT 5000
class LinkInsertionDialog : public QDialog
{
Q_OBJECT
public :
LinkInsertionDialog(KoTextEditor *editor, QWidget *parent = 0);
virtual ~LinkInsertionDialog();
private slots:
void insertLink();
public slots:
void fetchTitleFromURL();
void replyFinished();
void fetchTitleError(QNetworkReply::NetworkError);
void updateTitleDownloadProgress(qint64, qint64);
void fetchTitleTimeout();
/**
* Verifies the text entered in the four line edits : Weblink URL, Weblink text,
* Bookmark name and Bookmark text. The "Ok" button is enabled only if the input
* is valid.
* @param text is the text to be verified.
*/
void enableDisableButtons(QString text);
/**
* Once all the line edits for a tab have been verified, the OK button is enabled.
* If the tab is switched, the validity of OK should be recalculated for the new tab.
* @param text is the current active tab.
*/
void checkInsertEnableValidity(int);
private :
Ui::LinkInsertionDialog dlg;
KoTextEditor *m_editor;
const KoBookmarkManager *m_bookmarkManager;
QStringList m_bookmarkList;
QNetworkReply *m_reply;
QNetworkAccessManager *m_networkAccessManager;
QUrl m_linkURL;
QTimer m_timeoutTimer;
void accept();
void sendRequest();
void insertBookmarkLink(const QString &URL, const QString& text);
void insertHyperlink(QString &linkURL, const QString& linkText);
void displayInlineWarning(const QString &title, QLabel *label) const;
bool exists(const QString &) const;
};
#endif
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>LinkInsertionDialog</class>
<widget class="QDialog" name="LinkInsertionDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>567</width>
<height>241</height>
</rect>
</property>
<property name="windowTitle">
<string>Link</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QTabWidget" name="linkTypesTab">
<property name="toolTip">
<string/>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<property name="movable">
<bool>true</bool>
</property>
<widget class="QWidget" name="weblinkInsertionTab">
<attribute name="title">
<string>Web Link</string>
</attribute>
<attribute name="toolTip">
<string>Insert links to web documents. You can provide both URL and a label for the link,
or just enter the URL and hit &quot;Fetch the title from URL&quot;</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label_2">
<property name="toolTip">
<string>The address of your document ( Uniform Resource Locator)</string>
</property>
<property name="text">
<string> URL:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="0" column="1" colspan="2">
<widget class="QLineEdit" name="hyperlinkURL"/>
</item>
<item row="1" column="1">
<widget class="QPushButton" name="fetchTitleButton">
<property name="toolTip">
<string>Hit this button to get the title from the URL. Redirections are also handled. </string>
</property>
<property name="text">
<string>Fetch Title From URL</string>
</property>
</widget>
</item>
<item row="1" column="2">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>168</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label">
<property name="toolTip">
<string>The text that will be displayed for your link</string>
</property>
<property name="text">
<string> Text:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="2" column="1" colspan="2">
<widget class="QLineEdit" name="hyperlinkText"/>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="weblinkStatusLabel">
<property name="lineWidth">
<number>2</number>
</property>
<property name="text">
<string/>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="bookmarkLinkInsertionTab">
<attribute name="title">
<string>Link To Bookmark</string>
</attribute>
<attribute name="toolTip">
<string>Insert links to Bookmarks. To create bookmarks,
click &quot;Bookmarks&quot; in the Links and References section</string>
<