Version: 1.8.1 (using KDE KDE 3.4.1) Installed from: Debian testing/unstable Packages OS: Linux Kile v 1.8.1 does not allow dragging files from Konqueror or Krusader into the edit space. Please add such a feature to Kile.
*** Bug 121467 has been marked as a duplicate of this bug. ***
SVN commit 573922 by mludwig: Add drag-and-drop functionality as proposed in bug 114911. The sensitive areas for URL drops are the edit space (tab widget, editor) and the project view. (changes approved by Thomas Braun) FEATURE: 114911 M +15 -4 kiledocmanager.cpp M +5 -2 kiledocmanager.h M +10 -0 kileprojectview.cpp M +5 -0 kileprojectview.h M +71 -5 kileviewmanager.cpp M +30 -1 kileviewmanager.h --- trunk/extragear/office/kile/kile/kiledocmanager.cpp #573921:573922 @@ -5,6 +5,7 @@ // // // Author: Jeroen Wijnhout <Jeroen.Wijnhout@kdemail.net>, (C) 2004 +// Michel Ludwig <michel.ludwig@kdemail.net>, (C) 2006 // /*************************************************************************** @@ -35,6 +36,7 @@ #include <kio/netaccess.h> #include <kpushbutton.h> #include <kurl.h> +#include <kurldrag.h> #include "kileuntitled.h" #include "templates.h" @@ -525,7 +527,7 @@ return view; } -Kate::View* Manager::load(const KURL &url , const QString & encoding /* = QString::null */, bool create /* = true */, const QString & highlight /* = QString::null */, const QString & text /* = QString::null */) +Kate::View* Manager::load(const KURL &url , const QString & encoding /* = QString::null */, bool create /* = true */, const QString & highlight /* = QString::null */, const QString & text /* = QString::null */, int index /* = - 1 */) { kdDebug() << "==load(" << url.url() << ")=================" << endl; //if doc already opened, update the structure view and return the view @@ -542,7 +544,7 @@ //FIXME: use signal/slot if (doc && create) - return m_ki->viewManager()->createView(doc); + return m_ki->viewManager()->createView(doc, index); kdDebug() << "just after createView()" << endl; kdDebug() << "\tdocinfo = " << docinfo << " doc = " << docinfo->getDoc() << " docfor = " << docFor(docinfo->url().path()) << endl; @@ -784,7 +786,7 @@ } } -void Manager::fileOpen(const KURL & url, const QString & encoding) +void Manager::fileOpen(const KURL & url, const QString & encoding, int index) { kdDebug() << "==Kile::fileOpen==========================" << endl; @@ -798,7 +800,7 @@ bool isopen = m_ki->isOpen(realurl); - Kate::View *view = load(realurl, encoding); + Kate::View *view = load(realurl, encoding, true, QString::null, QString::null, index); KileProjectItem *item = itemFor(realurl); if(!isopen) @@ -1528,6 +1530,15 @@ docinfo->cleanTempFiles(extlist); } +void Manager::openDroppedUris(QDropEvent *e) { + KURL::List urls; + if(KURLDrag::decode(e, urls)) { + for(KURL::List::iterator i = urls.begin(); i != urls.end(); ++i) { + fileOpen(*i); + } + } +} + // Show all opened projects and switch to another one, if you want void Manager::projectShow() --- trunk/extragear/office/kile/kile/kiledocmanager.h #573921:573922 @@ -5,6 +5,7 @@ // // // Author: Jeroen Wijnhout <Jeroen.Wijnhout@kdemail.net>, (C) 2004 +// Michel Ludwig <michel.ludwig@kdemail.net>, (C) 2006 // // Copyright: See COPYING file that comes with this distribution // @@ -57,7 +58,7 @@ Kate::View* createDocumentWithText(const QString & text); - Kate::View* load( const KURL &url , const QString & encoding = QString::null, bool create = true, const QString & highlight = QString::null, const QString &text = QString::null); + Kate::View* load( const KURL &url , const QString & encoding = QString::null, bool create = true, const QString & highlight = QString::null, const QString &text = QString::null, int index = -1); Kate::View* loadItem(KileProjectItem *item, const QString & text = QString::null); void setHighlightMode(Kate::Document * doc, const QString & highlight = QString::null); @@ -72,7 +73,7 @@ void fileSelected(const KFileItem *file); void fileOpen(); - void fileOpen(const KURL& url, const QString & encoding = QString::null); + void fileOpen(const KURL& url, const QString & encoding = QString::null, int index = -1); void saveURL(const KURL &); void fileSaveAll(bool amAutoSaving = false, bool disUntitled = false); @@ -127,6 +128,8 @@ void cleanUpTempFiles(KileDocument::Info *docinfo = 0, bool silent = false); + void openDroppedUris(QDropEvent *e); + signals: void projectTreeChanged(const KileProject *); void closingDocument(KileDocument::Info *); --- trunk/extragear/office/kile/kile/kileprojectview.cpp #573921:573922 @@ -1,7 +1,9 @@ /*************************************************************************** begin : Tue Aug 12 2003 copyright : (C) 2003 by Jeroen Wijnhout + (C) 2006 by Michel Ludwig email : Jeroen.Wijnhout@kdemail.net + michel.ludwig@kdemail.net ***************************************************************************/ /*************************************************************************** @@ -22,6 +24,7 @@ #include <kurl.h> #include <krun.h> #include <kmimetype.h> +#include <kurldrag.h> #include "kileinfo.h" #include "kiledocumentinfo.h" @@ -89,6 +92,8 @@ connect(this, SIGNAL(contextMenu(KListView *, QListViewItem *, const QPoint & )), this,SLOT(popup(KListView *, QListViewItem * , const QPoint & ))); connect(this, SIGNAL(executed(QListViewItem*)), this, SLOT(slotClicked(QListViewItem*))); + setAcceptDrops(true); + connect(this, SIGNAL(dropped(QDropEvent *, QListViewItem *)), m_ki->docManager(), SLOT(openDroppedUris(QDropEvent *))); } void KileProjectView::slotClicked(QListViewItem *item) @@ -613,4 +618,9 @@ } +bool KileProjectView::acceptDrag(QDropEvent *e) const +{ + return KURLDrag::canDecode(e); // only accept URL drops +} + #include "kileprojectview.moc" --- trunk/extragear/office/kile/kile/kileprojectview.h #573921:573922 @@ -1,7 +1,9 @@ /*************************************************************************** begin : Tue Aug 12 2003 copyright : (C) 2003 by Jeroen Wijnhout + (C) 2006 by Michel Ludwig email : Jeroen.Wijnhout@kdemail.net + michel.ludwig@kdemail.net ***************************************************************************/ /*************************************************************************** @@ -129,6 +131,9 @@ KileProjectViewItem* itemFor(const KURL &); KileProjectViewItem* parentFor(const KileProjectItem *projitem, KileProjectViewItem *projvi); +protected: + virtual bool acceptDrag(QDropEvent *e) const; + private slots: void popup(KListView *, QListViewItem *, const QPoint &); --- trunk/extragear/office/kile/kile/kileviewmanager.cpp #573921:573922 @@ -5,6 +5,7 @@ // // // Author: Jeroen Wijnhout <Jeroen.Wijnhout@kdemail.net>, (C) 2004 +// Michel Ludwig <michel.ludwig@kdemail.net>, (C) 2006 /*************************************************************************** * * @@ -32,6 +33,7 @@ #include <klocale.h> #include <ktexteditor/editinterfaceext.h> #include <kapplication.h> +#include <kurldrag.h> #include "kileinfo.h" #include "kiledocmanager.h" @@ -50,7 +52,9 @@ m_ki(info), m_activeView(0L), // m_projectview(0L), - m_tabs(0L) + m_tabs(0L), + m_widgetStack(0L), + m_emptyDropWidget(0L) { } @@ -76,7 +80,13 @@ void Manager::createTabs(QWidget *parent) { + m_widgetStack = new QWidgetStack(parent); + m_emptyDropWidget = new DropWidget(parent); + m_widgetStack->addWidget(m_emptyDropWidget); + connect(m_emptyDropWidget, SIGNAL(testCanDecode(const QDragMoveEvent *, bool &)), this, SLOT(testCanDecodeURLs(const QDragMoveEvent *, bool &))); + connect(m_emptyDropWidget, SIGNAL(receivedDropEvent(QDropEvent *)), m_ki->docManager(), SLOT(openDroppedUris(QDropEvent *))); m_tabs = new KTabWidget(parent); + m_widgetStack->addWidget(m_tabs); m_tabs->setFocusPolicy(QWidget::ClickFocus); m_tabs->setTabReorderingEnabled(true); m_tabs->setHoverCloseButton(true); @@ -86,6 +96,10 @@ connect( m_tabs, SIGNAL( currentChanged( QWidget * ) ), m_receiver, SLOT(activateView( QWidget * )) ); connect( m_tabs, SIGNAL( currentChanged( QWidget * ) ), m_receiver, SLOT(updateModeStatus()) ); connect( m_tabs, SIGNAL( closeRequest(QWidget *) ), this, SLOT(closeWidget(QWidget *))); + connect( m_tabs, SIGNAL( testCanDecode( const QDragMoveEvent *, bool & ) ), this, SLOT(testCanDecodeURLs( const QDragMoveEvent *, bool & )) ); + connect( m_tabs, SIGNAL( receivedDropEvent( QDropEvent * ) ), m_ki->docManager(), SLOT(openDroppedUris( QDropEvent * )) ); + connect( m_tabs, SIGNAL( receivedDropEvent( QWidget*, QDropEvent * ) ), this, SLOT(replaceLoadedUri( QWidget *, QDropEvent * )) ); + m_widgetStack->raiseWidget(m_emptyDropWidget); // there are no tabs, so show the DropWidget } void Manager::closeWidget(QWidget *widget) @@ -97,7 +111,7 @@ } } -Kate::View* Manager::createView(Kate::Document *doc) +Kate::View* Manager::createView(Kate::Document *doc, int index) { Kate::View *view = (Kate::View*) doc->createView (m_tabs, 0L); @@ -105,13 +119,14 @@ view->focusProxy()->installEventFilter(m_ki->eventFilter()); //insert the view in the tab widget - m_tabs->addTab( view, m_ki->getShortName(doc) ); + m_tabs->insertTab( view, m_ki->getShortName(doc), index ); m_tabs->setTabToolTip(view, doc->url().url() ); m_tabs->showPage( view ); - m_viewList.append(view); + m_viewList.insert((index < 0 || (uint)index >= m_viewList.count()) ? m_viewList.count() : index, view); connect(view, SIGNAL(viewStatusMsg(const QString&)), m_receiver, SLOT(newStatus(const QString&))); connect(view, SIGNAL(newStatus()), m_receiver, SLOT(newCaption())); + connect(view, SIGNAL(dropEventPass(QDropEvent *)), m_ki->docManager(), SLOT(openDroppedUris(QDropEvent *))); connect( doc, SIGNAL(charactersInteractivelyInserted (int,int,const QString&)), m_ki->editorExtension()->complete(), SLOT(slotCharactersInserted(int,int,const QString&)) ); connect( view, SIGNAL(completionDone(KTextEditor::CompletionEntry)), m_ki->editorExtension()->complete(), SLOT( slotCompletionDone(KTextEditor::CompletionEntry)) ); @@ -154,6 +169,8 @@ action->unplugAll(); } + m_widgetStack->raiseWidget(m_tabs); // there is at least one tab, so show the KTabWidget now + return view; } @@ -168,7 +185,11 @@ delete view; QTimer::singleShot(0, m_receiver, SLOT(newCaption())); //make sure the caption gets updated - if (views().isEmpty()) m_ki->structureWidget()->clear(); + if (views().isEmpty()) { + m_ki->structureWidget()->clear(); + m_widgetStack->raiseWidget(m_emptyDropWidget); // there are no tabs left, so show + // the DropWidget + } } } @@ -399,6 +420,51 @@ editInterfaceExt->editEnd(); } + +void Manager::testCanDecodeURLs(const QDragMoveEvent *e, bool &accept) +{ + accept = KURLDrag::canDecode(e); // only accept URL drops } +void Manager::replaceLoadedUri(QWidget *w, QDropEvent *e) +{ + KURL::List urls; + if(!KURLDrag::decode(e, urls)) { + return; + } + int index = m_tabs->indexOf(w); + closeWidget(w); + for(KURL::List::iterator i = urls.begin(); i != urls.end(); ++i) { + if(i == urls.begin()) { + m_ki->docManager()->fileOpen(*i, QString::null, index); + } + else { + m_ki->docManager()->fileOpen(*i); + } + } +} + +DropWidget::DropWidget(QWidget * parent, const char * name, WFlags f) : QWidget(parent, name, f) +{ + setAcceptDrops(true); +} + +DropWidget::~DropWidget() +{ +} + +void DropWidget::dragMoveEvent(QDragMoveEvent *e) +{ + bool b; + emit testCanDecode(e, b); + e->accept(b); +} + +void DropWidget::dropEvent(QDropEvent *e) +{ + emit receivedDropEvent(e); +} + +} + #include "kileviewmanager.moc" --- trunk/extragear/office/kile/kile/kileviewmanager.h #573921:573922 @@ -5,6 +5,7 @@ // // // Author: Jeroen Wijnhout <Jeroen.Wijnhout@kdemail.net>, (C) 2004 +// Michel Ludwig <michel.ludwig@kdemail.net>, (C) 2006 // /*************************************************************************** @@ -20,6 +21,7 @@ #define KILEVIEWKILEVIEWMANAGER_H #include <qobject.h> +#include <qwidgetstack.h> #include <ktabwidget.h> @@ -61,7 +63,7 @@ Kate::View* view(int i) { return m_viewList.at(i); } void createTabs(QWidget *); - Kate::View* createView(Kate::Document *doc); + Kate::View* createView(Kate::Document *doc, int index = -1); KTabWidget* tabs() { return m_tabs; } // void setProjectView(KileProjectView *view) { m_projectview = view; } @@ -87,6 +89,10 @@ void convertSelectionToLaTeX(void); void pasteAsLaTeX(void); +protected slots: + void testCanDecodeURLs(const QDragMoveEvent *e, bool &accept); + void replaceLoadedUri(QWidget *w, QDropEvent *e); + signals: void activateView(QWidget *, bool); void prepareForPart(const QString &); @@ -100,8 +106,31 @@ KTabWidget *m_tabs; QObject *m_receiver; KXMLGUIClient *m_client; + QWidgetStack *m_widgetStack; + QWidget *m_emptyDropWidget; + }; +/** + * Little helper widget to overcome the limitation that KTabWidget doesn't honour drop events when + * there are no tabs: the DropWidget is shown instead of KTabWidget when there are no tabs. + */ +class DropWidget : public QWidget { + Q_OBJECT + + public: + DropWidget(QWidget * parent = 0, const char * name = 0, WFlags f = 0); + virtual ~DropWidget(); + + virtual void dragMoveEvent(QDragMoveEvent *e); + + virtual void dropEvent(QDropEvent *e); + + signals: + void testCanDecode(const QDragMoveEvent *, bool &); + void receivedDropEvent(QDropEvent *); +}; + } #endif