File indexing completed on 2024-05-12 16:35:23

0001 /* This file is part of the KDE project
0002    Copyright (C) 2005 Ariya Hidayat <ariya@kde.org>
0003              (C) 2003 Norbert Andres <nandres@web.de>
0004              (C) 2002 Philipp Mueller <philipp.mueller@gmx.de>
0005              (C) 1999-2002 Laurent Montel <montel@kde.org>
0006              (C) 1999 Stephan Kulow <coolo@kde.org>
0007              (C) 1998-1999 Torben Weis <weis@kde.org>
0008 
0009    This library is free software; you can redistribute it and/or
0010    modify it under the terms of the GNU Library General Public
0011    License as published by the Free Software Foundation; either
0012    version 2 of the License, or (at your option) any later version.
0013 
0014    This library is distributed in the hope that it will be useful,
0015    but WITHOUT ANY WARRANTY; without even the implied warranty of
0016    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0017    Library General Public License for more details.
0018 
0019    You should have received a copy of the GNU Library General Public License
0020    along with this library; see the file COPYING.LIB.  If not, write to
0021    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0022    Boston, MA 02110-1301, USA.
0023 */
0024 
0025 #include "LinkDialog.h"
0026 
0027 #include "Cell.h"
0028 #include "Map.h"
0029 #include "NamedAreaManager.h"
0030 #include "ui/Selection.h"
0031 #include "Sheet.h"
0032 
0033 #include <KoIcon.h>
0034 
0035 #include <QLabel>
0036 #include <QUrl>
0037 #include <QUrlQuery>
0038 #include <QVBoxLayout>
0039 
0040 #include <kcombobox.h>
0041 #include <kdesktopfile.h>
0042 #include <klineedit.h>
0043 #include <kmessagebox.h>
0044 #include <KLocalizedString>
0045 #include <krecentdocument.h>
0046 #include <kurlrequester.h>
0047 #include <kurlcompletion.h>
0048 
0049 using namespace Calligra::Sheets;
0050 
0051 class LinkDialog::Private
0052 {
0053 public:
0054     QString text;
0055     QWidget* internetPage;
0056     KLineEdit* internetText;
0057     KLineEdit* internetLink;
0058     QWidget* mailPage;
0059     KLineEdit* mailText;
0060     KLineEdit* mailLink;
0061     KLineEdit* mailSubject;
0062     QWidget* filePage;
0063     KLineEdit* fileText;
0064     KUrlRequester* fileLink;
0065     QWidget* cellPage;
0066     KLineEdit* cellText;
0067     KComboBox* cellLink;
0068     KPageWidgetItem* p1, *p2, *p3, *p4;
0069 };
0070 
0071 LinkDialog::LinkDialog(QWidget* parent, Selection* selection)
0072         : KPageDialog(parent)
0073         , d(new Private)
0074 {
0075     setWindowTitle(i18n("Insert Link"));
0076     setFaceType(List);
0077 
0078     // link for web or ftp
0079     d->internetPage = new QWidget();
0080     d->p1 = addPage(d->internetPage, i18n("Internet"));
0081     d->p1->setHeader(i18n("Link to Internet Address"));
0082     d->p1->setIcon(koIcon("internet-web-browser"));
0083     QVBoxLayout* iLayout = new QVBoxLayout(d->internetPage);
0084     iLayout->addWidget(new QLabel(i18n("Text to display:"), d->internetPage));
0085     d->internetText = new KLineEdit(d->internetPage);
0086     iLayout->addWidget(d->internetText);
0087     iLayout->addWidget(new QLabel(i18n("Internet address:"), d->internetPage));
0088     d->internetLink = new KLineEdit(d->internetPage);
0089     iLayout->addWidget(d->internetLink);
0090     iLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding));
0091     connect(d->internetText, SIGNAL(textChanged(QString)), this,
0092             SLOT(setText(QString)));
0093 
0094     // link for e-mail
0095     d->mailPage = new QWidget();
0096     d->p2 = addPage(d->mailPage, i18n("Email"));
0097     d->p2->setHeader(i18n("Link to Email Address"));
0098     d->p2->setIcon(koIcon("internet-mail"));
0099     QVBoxLayout* mLayout = new QVBoxLayout(d->mailPage);
0100     mLayout->addWidget(new QLabel(i18n("Text to display:"), d->mailPage));
0101     d->mailText = new KLineEdit(d->mailPage);
0102     mLayout->addWidget(d->mailText);
0103     mLayout->addWidget(new QLabel(i18n("Email address:"), d->mailPage));
0104     d->mailLink = new KLineEdit(d->mailPage);
0105     mLayout->addWidget(d->mailLink);
0106     connect(d->mailText, SIGNAL(textChanged(QString)), this,
0107             SLOT(setText(QString)));
0108     mLayout->addWidget(new QLabel(i18n("Subject:"), d->mailPage));
0109     d->mailSubject = new KLineEdit(d->mailPage);
0110     mLayout->addWidget(d->mailSubject);
0111     mLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding));
0112 
0113     // link for external file
0114     d->filePage = new QWidget();
0115     d->p3 = addPage(d->filePage, i18n("File"));
0116     d->p3->setHeader(i18n("Link to File"));
0117     d->p3->setIcon(koIcon("system-file-manager"));
0118     QVBoxLayout* fLayout = new QVBoxLayout(d->filePage);
0119     fLayout->addWidget(new QLabel(i18n("Text to display:"), d->filePage));
0120     d->fileText = new KLineEdit(d->filePage);
0121     fLayout->addWidget(d->fileText);
0122     fLayout->addWidget(new QLabel(i18n("File location:"), d->filePage));
0123     d->fileLink = new KUrlRequester(d->filePage);
0124     d->fileLink->completionObject()->setReplaceHome(true);
0125     d->fileLink->completionObject()->setReplaceEnv(true);
0126     fLayout->addWidget(d->fileLink);
0127     fLayout->addWidget(new QLabel(i18n("Recent file:"), d->filePage));
0128     KComboBox* recentFile = new KComboBox(d->filePage);
0129     recentFile->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
0130     recentFile->setMinimumContentsLength(40);
0131     fLayout->addWidget(recentFile);
0132     fLayout->addItem(new QSpacerItem(0, 40, QSizePolicy::Minimum, QSizePolicy::MinimumExpanding));
0133     connect(d->fileText, SIGNAL(textChanged(QString)), this,
0134             SLOT(setText(QString)));
0135     QObject::connect(recentFile, SIGNAL(highlighted(QString)),
0136                      d->fileLink->lineEdit(), SLOT(setText(QString)));
0137 
0138     // populate recent files
0139     int index = 0;
0140     const QStringList fileList = KRecentDocument::recentDocuments();
0141     for (QStringList::ConstIterator it = fileList.constBegin(); it != fileList.constEnd(); ++it) {
0142         KDesktopFile f(*it);
0143         if (!f.readUrl().isEmpty())
0144             recentFile->insertItem(index++, f.readUrl());
0145     }
0146     if (recentFile->count() == 0) {
0147         recentFile->insertItem(0, i18n("No Entries"));
0148         recentFile->setEnabled(false);
0149     }
0150 
0151     // link to another cell
0152     d->cellPage = new QWidget();
0153     d->p4 = addPage(d->cellPage, i18n("Cell"));
0154     d->p4->setHeader(i18n("Link to Cell"));
0155     d->p4->setIcon(koIcon("table"));
0156     QVBoxLayout* cLayout = new QVBoxLayout(d->cellPage);
0157     cLayout->addWidget(new QLabel(i18n("Text to display:"), d->cellPage));
0158     d->cellText = new KLineEdit(d->cellPage);
0159     cLayout->addWidget(d->cellText);
0160     cLayout->addWidget(new QLabel(i18n("Cell or Named Area:"), d->cellPage));
0161     d->cellLink = new KComboBox(d->cellPage);
0162     d->cellLink->setEditable(true);
0163 
0164     const Sheet *sheet = selection->activeSheet();
0165     if (sheet && selection) {
0166         Cell cell(sheet, selection->cursor());
0167         d->cellLink->addItem(cell.fullName());
0168     }
0169 
0170     const NamedAreaManager *manager = selection->activeSheet()->map()->namedAreaManager();
0171     d->cellLink->addItems(manager->areaNames());
0172 
0173     d->cellLink->setItemText(d->cellLink->currentIndex(), "");
0174     cLayout->addWidget(d->cellLink);
0175     cLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding));
0176     connect(d->cellText, SIGNAL(textChanged(QString)), this,
0177             SLOT(setText(QString)));
0178 
0179     d->internetText->setFocus();
0180     resize(400, 300);
0181     connect(this, SIGNAL(accepted()), this, SLOT(slotOk()));
0182 }
0183 
0184 LinkDialog::~LinkDialog()
0185 {
0186     delete d;
0187 }
0188 
0189 QString LinkDialog::text() const
0190 {
0191     return d->text;
0192 }
0193 
0194 QString LinkDialog::link() const
0195 {
0196     QString str;
0197     if (currentPage() == d->p1) {
0198         str = d->internetLink->text();
0199         if (!str.isEmpty())
0200             if (str.indexOf("http://") == -1)
0201                 if (str.indexOf("https://") == -1)
0202                     if (str.indexOf("ftp://") == -1)
0203                         str.prepend("http://");
0204     } else if (currentPage() == d->p2) {
0205         str = d->mailLink->text();
0206         if (!str.isEmpty())
0207             if (str.indexOf("mailto:") == -1)
0208                 str.prepend("mailto:");
0209         const QString subject = d->mailSubject->text().trimmed();
0210         if (! subject.isEmpty())
0211             str.append(QString("?subject=%1").arg(QString(QUrl::toPercentEncoding(subject))));
0212     } else if (currentPage() == d->p3) {
0213         QUrl url = d->fileLink->url();
0214         if (url.isValid()) {
0215             str = url.url();
0216         } else {
0217             str = d->fileText->text();
0218             if (!str.isEmpty())
0219                 if (! str.contains(QRegExp("^(file|mailto|http|https|ftp):")))
0220                     str.prepend("file://");
0221         }
0222     } else if (currentPage() == d->p4) {
0223         str = d->cellLink->currentText();
0224     }
0225 
0226     return str;
0227 }
0228 
0229 void LinkDialog::setText(const QString& text)
0230 {
0231     d->text = text;
0232 
0233     d->internetText->blockSignals(true);
0234     d->internetText->setText(text);
0235     d->internetText->blockSignals(false);
0236 
0237     d->mailText->blockSignals(true);
0238     d->mailText->setText(text);
0239     d->mailText->blockSignals(false);
0240 
0241     d->fileText->blockSignals(true);
0242     d->fileText->setText(text);
0243     d->fileText->blockSignals(false);
0244 
0245     d->cellText->blockSignals(true);
0246     d->cellText->setText(text);
0247     d->cellText->blockSignals(false);
0248 }
0249 
0250 // link must be complete, e.g. "http://www.calligra.org" instead of
0251 // "www.calligra.org" only, since protocol is used to decide which page to show
0252 void LinkDialog::setLink(const QString& link)
0253 {
0254     if (link.startsWith(QLatin1String("https://"))) {
0255         d->internetLink->setText(link.mid(8));
0256         setCurrentPage(d->p1);
0257         return;
0258     }
0259 
0260     if (link.startsWith(QLatin1String("http://"))) {
0261         d->internetLink->setText(link.mid(7));
0262         setCurrentPage(d->p1);
0263         return;
0264     }
0265 
0266     if (link.startsWith(QLatin1String("ftp://"))) {
0267         d->internetLink->setText(link.mid(6));
0268         setCurrentPage(d->p1);
0269         return;
0270     }
0271 
0272     if (link.startsWith(QLatin1String("mailto:"))) {
0273         QUrl url(link);
0274         if (url.isValid()) {
0275             d->mailLink->setText(url.toString(QUrl::RemoveScheme | QUrl::RemoveQuery));
0276             d->mailSubject->setText(QUrlQuery(url).queryItemValue("subject"));
0277         } else {
0278             d->mailLink->setText(link.mid(7));
0279         }
0280         setCurrentPage(d->p2);
0281         return;
0282     }
0283 
0284     if (link.startsWith(QLatin1String("file:/"))) {
0285         QString s = link.mid(6);
0286         while (s.startsWith(QLatin1String("//"))) s.remove(0, 1);
0287         d->fileLink->lineEdit()->setText(s);
0288         setCurrentPage(d->p3);
0289         return;
0290     }
0291 
0292     // assume cell reference
0293     d->cellLink->setItemText(d->cellLink->currentIndex(), link);
0294     setCurrentPage(d->p4);
0295 }
0296 
0297 void LinkDialog::slotOk()
0298 {
0299     QString str;
0300 
0301     if (currentPage() == d->p1)
0302         str = i18n("Internet address is empty");
0303     else if (currentPage() == d->p2)
0304         str = i18n("Mail address is empty");
0305     else if (currentPage() == d->p3)
0306         str = i18n("File name is empty");
0307     else if (currentPage() == d->p4)
0308         i18n("Destination cell is empty");
0309 
0310     if (link().isEmpty()) {
0311         KMessageBox::error(this, str);
0312         return;
0313     }
0314 
0315     if (d->text.isEmpty())
0316         d->text = link();
0317 
0318     accept();
0319 }