lineedit.cpp 6.49 KB
Newer Older
1 2 3
/*
 *  lineedit.cpp  -  Line edit widget with extra drag and drop options
 *  Program:  kalarm
David Jarvie's avatar
David Jarvie committed
4
 *  Copyright © 2003-2005,2009-2010 by David Jarvie <djarvie@kde.org>
5 6 7 8 9 10 11 12 13 14 15
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program 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 General Public License for more details.
 *
David Jarvie's avatar
David Jarvie committed
16 17 18
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 20 21
 */

#include "kalarm.h"
Laurent Montel's avatar
Laurent Montel committed
22
#include "lineedit.h"
23

Laurent Montel's avatar
Laurent Montel committed
24
#include <libkdepim/misc/maillistdrag.h>
Aleix Pol Gonzalez's avatar
Aleix Pol Gonzalez committed
25
#include <kcontacts/vcarddrag.h>
Laurent Montel's avatar
Laurent Montel committed
26
#include <KCalUtils/kcalutils/icaldrag.h>
27 28 29 30

#include <kurl.h>
#include <kurlcompletion.h>
#include <kshell.h>
31

David Jarvie's avatar
David Jarvie committed
32
#include <QRegExp>
David Jarvie's avatar
David Jarvie committed
33
#include <QMimeData>
Laurent Montel's avatar
Qt3to4  
Laurent Montel committed
34 35
#include <QDragEnterEvent>
#include <QDropEvent>
David Jarvie's avatar
David Jarvie committed
36
#include <QFocusEvent>
37 38 39 40 41 42 43 44


/*=============================================================================
= Class LineEdit
= Line edit which accepts drag and drop of text, URLs and/or email addresses.
* It has an option to prevent its contents being selected when it receives
= focus.
=============================================================================*/
David Jarvie's avatar
David Jarvie committed
45
LineEdit::LineEdit(Type type, QWidget* parent)
46 47 48 49
    : KLineEdit(parent),
      mType(type),
      mNoSelect(false),
      mSetCursorAtEnd(false)
50
{
51
    init();
52 53
}

David Jarvie's avatar
David Jarvie committed
54
LineEdit::LineEdit(QWidget* parent)
55 56 57 58
    : KLineEdit(parent),
      mType(Text),
      mNoSelect(false),
      mSetCursorAtEnd(false)
59
{
60
    init();
61 62 63 64
}

void LineEdit::init()
{
65 66
    if (mType == Url)
    {
Laurent Montel's avatar
Laurent Montel committed
67
        setCompletionMode(KCompletion::CompletionShell);
68 69 70 71 72
        KUrlCompletion* comp = new KUrlCompletion(KUrlCompletion::FileCompletion);
        comp->setReplaceHome(true);
        setCompletionObject(comp);
        setAutoDeleteCompletionObject(true);
    }
Laurent Montel's avatar
Laurent Montel committed
73
    else 
Laurent Montel's avatar
Laurent Montel committed
74
        setCompletionMode(KCompletion::CompletionNone);
75 76 77 78 79 80 81 82
}

/******************************************************************************
*  Called when the line edit receives focus.
*  If 'noSelect' is true, prevent the contents being selected.
*/
void LineEdit::focusInEvent(QFocusEvent* e)
{
83 84 85
    QFocusEvent newe(QEvent::FocusIn, (mNoSelect ? Qt::OtherFocusReason : e->reason()));
    KLineEdit::focusInEvent(&newe);
    mNoSelect = false;
86 87
}

88 89
QString LineEdit::text() const
{
90 91 92
    if (mType == Url)
        return KShell::tildeExpand(KLineEdit::text());
    return KLineEdit::text();
93 94
}

95 96
void LineEdit::setText(const QString& text)
{
97 98
    KLineEdit::setText(text);
    setCursorPosition(mSetCursorAtEnd ? text.length() : 0);
99 100 101 102
}

void LineEdit::dragEnterEvent(QDragEnterEvent* e)
{
103 104 105 106 107 108 109 110
    const QMimeData* data = e->mimeData();
    bool ok;
    if (KCalUtils::ICalDrag::canDecode(data))
        ok = false;   // don't accept "text/calendar" objects
    else
        ok = (data->hasText()
           || KUrl::List::canDecode(data)
           || (mType != Url && KPIM::MailList::canDecode(data))
Aleix Pol Gonzalez's avatar
Aleix Pol Gonzalez committed
111
           || (mType == Emails && KContacts::VCardDrag::canDecode(data)));
112 113 114 115
    if (ok)
        e->accept(rect());
    else
        e->ignore(rect());
116 117 118 119
}

void LineEdit::dropEvent(QDropEvent* e)
{
120 121 122 123
    const QMimeData* data = e->mimeData();
    QString               newText;
    QStringList           newEmails;
    KUrl::List            files;
Aleix Pol Gonzalez's avatar
Aleix Pol Gonzalez committed
124
    KContacts::Addressee::List addrList;
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140

    if (mType != Url
    &&  KPIM::MailList::canDecode(data))
    {
        KPIM::MailList mailList = KPIM::MailList::fromMimeData(data);
        // KMail message(s) - ignore all but the first
        if (mailList.count())
        {
            if (mType == Emails)
                newText = mailList.first().from();
            else
                setText(mailList.first().subject());    // replace any existing text
        }
    }
    // This must come before KUrl
    else if (mType == Emails
Aleix Pol Gonzalez's avatar
Aleix Pol Gonzalez committed
141
    &&  KContacts::VCardDrag::canDecode(data)  &&  KContacts::VCardDrag::fromMimeData(data, addrList))
142 143
    {
        // KAddressBook entries
Aleix Pol Gonzalez's avatar
Aleix Pol Gonzalez committed
144
        for (KContacts::Addressee::List::Iterator it = addrList.begin();  it != addrList.end();  ++it)
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
        {
            QString em((*it).fullEmail());
            if (!em.isEmpty())
                newEmails.append(em);
        }
    }
    else if (!(files = KUrl::List::fromMimeData(data)).isEmpty())
    {
        // URL(s)
        switch (mType)
        {
            case Url:
                // URL entry field - ignore all but the first dropped URL
                setText(files.first().prettyUrl());    // replace any existing text
                break;
            case Emails:
            {
                // Email entry field - ignore all but mailto: URLs
                QString mailto = QLatin1String("mailto");
                for (KUrl::List::Iterator it = files.begin();  it != files.end();  ++it)
                {
Laurent Montel's avatar
Laurent Montel committed
166
                    if ((*it).scheme() == mailto)
167 168 169 170 171 172 173 174 175 176 177 178 179 180 181
                        newEmails.append((*it).path());
                }
                break;
            }
            case Text:
                newText = files.first().prettyUrl();
                break;
        }
    }
    else if (data->hasText())
    {
        // Plain text
        QString txt = data->text();
        if (mType == Emails)
        {
Laurent Montel's avatar
Laurent Montel committed
182
            // Remove newlines from a list of email addresses, and allow an eventual mailto: scheme
183
            QString mailto = QLatin1String("mailto:");
Laurent Montel's avatar
Laurent Montel committed
184
            newEmails = txt.split(QRegExp(QLatin1String("[\r\n]+")), QString::SkipEmptyParts);
185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202
            for (QStringList::Iterator it = newEmails.begin();  it != newEmails.end();  ++it)
            {
                if ((*it).startsWith(mailto))
                {
                    KUrl url(*it);
                    *it = url.path();
                }
            }
        }
        else
        {
            int newline = txt.indexOf(QLatin1Char('\n'));
            newText = (newline >= 0) ? txt.left(newline) : txt;
        }
    }

    if (newEmails.count())
    {
Laurent Montel's avatar
Laurent Montel committed
203
        newText = newEmails.join(QLatin1String(","));
204 205
        int c = cursorPosition();
        if (c > 0)
Laurent Montel's avatar
Laurent Montel committed
206
            newText.prepend(QLatin1String(","));
207
        if (c < static_cast<int>(text().length()))
Laurent Montel's avatar
Laurent Montel committed
208
            newText.append(QLatin1String(","));
209 210 211
    }
    if (!newText.isEmpty())
        insert(newText);
212
}
213

214
// vim: et sw=4: