lineedit.cpp
00001 /* 00002 * lineedit.cpp - Line edit widget with extra drag and drop options 00003 * Program: kalarm 00004 * Copyright (C) 2003 - 2005 by David Jarvie <software@astrojar.org.uk> 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License along 00017 * with this program; if not, write to the Free Software Foundation, Inc., 00018 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00019 */ 00020 00021 #include "kalarm.h" 00022 00023 #include <tqregexp.h> 00024 #include <tqdragobject.h> 00025 00026 #include <kurldrag.h> 00027 #include <kurlcompletion.h> 00028 00029 #include <libtdepim/maillistdrag.h> 00030 #include <libtdepim/kvcarddrag.h> 00031 #include <libkcal/icaldrag.h> 00032 00033 #include "lineedit.moc" 00034 00035 00036 /*============================================================================= 00037 = Class LineEdit 00038 = Line edit which accepts drag and drop of text, URLs and/or email addresses. 00039 * It has an option to prevent its contents being selected when it receives 00040 = focus. 00041 =============================================================================*/ 00042 LineEdit::LineEdit(Type type, TQWidget* parent, const char* name) 00043 : KLineEdit(parent, name), 00044 mType(type), 00045 mNoSelect(false), 00046 mSetCursorAtEnd(false) 00047 { 00048 init(); 00049 } 00050 00051 LineEdit::LineEdit(TQWidget* parent, const char* name) 00052 : KLineEdit(parent, name), 00053 mType(Text), 00054 mNoSelect(false), 00055 mSetCursorAtEnd(false) 00056 { 00057 init(); 00058 } 00059 00060 void LineEdit::init() 00061 { 00062 if (mType == Url) 00063 { 00064 setCompletionMode(TDEGlobalSettings::CompletionShell); 00065 KURLCompletion* comp = new KURLCompletion(KURLCompletion::FileCompletion); 00066 comp->setReplaceHome(true); 00067 setCompletionObject(comp); 00068 setAutoDeleteCompletionObject(true); 00069 } 00070 else 00071 setCompletionMode(TDEGlobalSettings::CompletionNone); 00072 } 00073 00074 /****************************************************************************** 00075 * Called when the line edit receives focus. 00076 * If 'noSelect' is true, prevent the contents being selected. 00077 */ 00078 void LineEdit::focusInEvent(TQFocusEvent* e) 00079 { 00080 if (mNoSelect) 00081 e->setReason(TQFocusEvent::Other); 00082 KLineEdit::focusInEvent(e); 00083 if (mNoSelect) 00084 { 00085 e->resetReason(); 00086 mNoSelect = false; 00087 } 00088 } 00089 00090 void LineEdit::setText(const TQString& text) 00091 { 00092 KLineEdit::setText(text); 00093 setCursorPosition(mSetCursorAtEnd ? text.length() : 0); 00094 } 00095 00096 void LineEdit::dragEnterEvent(TQDragEnterEvent* e) 00097 { 00098 if (KCal::ICalDrag::canDecode(e)) 00099 e->accept(false); // don't accept "text/calendar" objects 00100 e->accept(TQTextDrag::canDecode(e) 00101 || KURLDrag::canDecode(e) 00102 || (mType != Url && KPIM::MailListDrag::canDecode(e)) 00103 || (mType == Emails && KVCardDrag::canDecode(e))); 00104 } 00105 00106 void LineEdit::dropEvent(TQDropEvent* e) 00107 { 00108 TQString newText; 00109 TQStringList newEmails; 00110 TQString txt; 00111 KPIM::MailList mailList; 00112 KURL::List files; 00113 TDEABC::Addressee::List addrList; 00114 00115 if (mType != Url 00116 && e->provides(KPIM::MailListDrag::format()) 00117 && KPIM::MailListDrag::decode(e, mailList)) 00118 { 00119 // KMail message(s) - ignore all but the first 00120 if (mailList.count()) 00121 { 00122 if (mType == Emails) 00123 newText = mailList.first().from(); 00124 else 00125 setText(mailList.first().subject()); // replace any existing text 00126 } 00127 } 00128 // This must come before KURLDrag 00129 else if (mType == Emails 00130 && KVCardDrag::canDecode(e) && KVCardDrag::decode(e, addrList)) 00131 { 00132 // KAddressBook entries 00133 for (TDEABC::Addressee::List::Iterator it = addrList.begin(); it != addrList.end(); ++it) 00134 { 00135 TQString em((*it).fullEmail()); 00136 if (!em.isEmpty()) 00137 newEmails.append(em); 00138 } 00139 } 00140 else if (KURLDrag::decode(e, files) && files.count()) 00141 { 00142 // URL(s) 00143 switch (mType) 00144 { 00145 case Url: 00146 // URL entry field - ignore all but the first dropped URL 00147 setText(files.first().prettyURL()); // replace any existing text 00148 break; 00149 case Emails: 00150 { 00151 // Email entry field - ignore all but mailto: URLs 00152 TQString mailto = TQString::fromLatin1("mailto"); 00153 for (KURL::List::Iterator it = files.begin(); it != files.end(); ++it) 00154 { 00155 if ((*it).protocol() == mailto) 00156 newEmails.append((*it).path()); 00157 } 00158 break; 00159 } 00160 case Text: 00161 newText = files.first().prettyURL(); 00162 break; 00163 } 00164 } 00165 else if (TQTextDrag::decode(e, txt)) 00166 { 00167 // Plain text 00168 if (mType == Emails) 00169 { 00170 // Remove newlines from a list of email addresses, and allow an eventual mailto: protocol 00171 TQString mailto = TQString::fromLatin1("mailto:"); 00172 newEmails = TQStringList::split(TQRegExp("[\r\n]+"), txt); 00173 for (TQStringList::Iterator it = newEmails.begin(); it != newEmails.end(); ++it) 00174 { 00175 if ((*it).startsWith(mailto)) 00176 { 00177 KURL url(*it); 00178 *it = url.path(); 00179 } 00180 } 00181 } 00182 else 00183 { 00184 int newline = txt.find('\n'); 00185 newText = (newline >= 0) ? txt.left(newline) : txt; 00186 } 00187 } 00188 00189 if (newEmails.count()) 00190 { 00191 newText = newEmails.join(","); 00192 int c = cursorPosition(); 00193 if (c > 0) 00194 newText.prepend(","); 00195 if (c < static_cast<int>(text().length())) 00196 newText.append(","); 00197 } 00198 if (!newText.isEmpty()) 00199 insert(newText); 00200 }