You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdevelop/src/editorproxy.cpp

298 lines
7.7 KiB

#include <tqwidget.h>
#include <tqpopupmenu.h>
#include <tqtimer.h>
#include <tdeversion.h>
#include <kdebug.h>
#include <tdeconfig.h>
#include <tdeapplication.h>
#include <tdeparts/part.h>
#include <tdetexteditor/document.h>
#include <tdetexteditor/view.h>
#include <tdetexteditor/viewcursorinterface.h>
#include <tdetexteditor/popupmenuinterface.h>
#include <tdetexteditor/editinterface.h>
#include <tdetexteditor/selectioninterface.h>
#include <tdetexteditor/view.h>
#include <kxmlguiclient.h>
#include <kxmlguifactory.h>
#include <tdemainwindow.h>
#include <tdeactioncollection.h>
#include <tdelocale.h>
#include <tdestdaccel.h>
#include "toplevel.h"
#include "partcontroller.h"
#include "core.h"
#include "multibuffer.h"
#include "kdeveditorutil.h"
#include "editorproxy.h"
using namespace KTextEditor;
EditorProxy *EditorProxy::s_instance = 0;
EditorProxy::EditorProxy()
: TQObject()
{
m_delayedLineTimer = new TQTimer( this );
connect( m_delayedLineTimer, TQ_SIGNAL( timeout() ), this, TQ_SLOT(setLineNumberDelayed()) );
TDEConfig *config = kapp->config();
m_delayedViewCreationCompatibleUI = true;
TDEAction *ac = new TDEAction( i18n("Show Context Menu"), 0, this,
TQ_SLOT(showPopup()), TopLevel::getInstance()->main()->actionCollection(), "show_popup" );
TDEShortcut cut ;/*= TDEStdAccel::shortcut(TDEStdAccel::PopupMenuContext);*/
cut.append(KKey(CTRL+Key_Return));
ac->setShortcut(cut);
}
EditorProxy *EditorProxy::getInstance()
{
if (!s_instance)
s_instance = new EditorProxy;
return s_instance;
}
void EditorProxy::setLineNumberDelayed()
{
if( !this ) return; ///This should fix a strange crash I use to encounter, where setLineNumberDelayed is called with this == NULL
setLineNumber(m_delayedPart, m_delayedLine, m_delayedCol);
}
void EditorProxy::setLineNumber(KParts::Part *part, int lineNum, int col)
{
if (!part || !part->inherits("KTextEditor::Document"))
return;
if ( lineNum < 0 )
return;
KURL url = dynamic_cast<KParts::ReadOnlyPart*>( part )->url();
ViewCursorInterface *iface = dynamic_cast<ViewCursorInterface*>(part->widget());
if (iface)
{
#if KDE_IS_VERSION(3,5,5)
#else
if (!part->widget()->hasFocus()) //workaround for TQXIMInputContext crashes. Keep for KDE <=3.5.4!
{
m_delayedPart = part;
m_delayedLine = lineNum;
m_delayedCol = col;
m_delayedLineTimer->start( 1, true );
} else
#endif
iface->setCursorPositionReal(lineNum, col == -1 ? 0 : col);
}
else {
// Save the position for a rainy day (or when the view gets activated and wants its position)
for (TQValueList<MultiBuffer*>::ConstIterator it = m_editorParts.begin(); it != m_editorParts.end(); ++it)
if ((*it)->hasURL( url )) {
(*it)->registerDelayedActivation( part, lineNum, col );
return;
}
// Shouldn't hit this?
Q_ASSERT(false);
}
}
void EditorProxy::installPopup( KParts::Part * part )
{
if ( part->inherits("KTextEditor::Document") && part->widget())
{
PopupMenuInterface *iface = dynamic_cast<PopupMenuInterface*>(part->widget());
if (iface)
{
KTextEditor::View * view = static_cast<KTextEditor::View*>( part->widget() );
TQPopupMenu * popup = static_cast<TQPopupMenu*>( part->factory()->container("tdetexteditor_popup", view ) );
if (!popup)
{
kdWarning() << k_funcinfo << "Popup not found!" << endl;
return;
}
TDEAction * action = NULL;
//If there is a tab for this file, we don't need to plug the closing menu entries here
TDEConfig *config = TDEGlobal::config();
config->setGroup("UI");
bool m_tabBarShown = ! config->readNumEntry("TabWidgetVisibility", 0);
if (!m_tabBarShown)
{
action = TopLevel::getInstance()->main()->actionCollection()->action( "file_close" );
if ( action && !action->isPlugged( popup ) )
{
popup->insertSeparator( 0 );
action->plug( popup, 0 );
}
action = TopLevel::getInstance()->main()->actionCollection()->action( "file_closeother" );
if ( action && !action->isPlugged( popup ) )
action->plug( popup, 1 );
}
iface->installPopup( popup );
connect(popup, TQ_SIGNAL(aboutToShow()), this, TQ_SLOT(popupAboutToShow()));
// ugly hack: mark the "original" items
m_popupIds.resize(popup->count());
for (uint index=0; index < popup->count(); ++index)
m_popupIds[index] = popup->idAt(index);
}
}
}
void EditorProxy::popupAboutToShow()
{
TQPopupMenu *popup = (TQPopupMenu*)sender();
if (!popup)
return;
// ugly hack: remove all but the "original" items
for (int index=popup->count()-1; index >= 0; --index)
{
int id = popup->idAt(index);
if (m_popupIds.contains(id) == 0)
{
TQMenuItem *item = popup->findItem(id);
if ( item && item->popup() )
delete item->popup();
else
popup->removeItemAt(index);
}
}
KTextEditor::Document * doc = dynamic_cast<KTextEditor::Document*>( PartController::getInstance()->activePart() );
if (!doc ) return;
unsigned int line;
unsigned int col;
if ( !KDevEditorUtil::currentPositionReal( &line, &col, doc ) ) return;
TQString wordstr;
TQString selection = KDevEditorUtil::currentSelection( doc );
if ( !selection.isEmpty() && selection.contains('\n') != 0 )
{
wordstr = selection;
}
else
{
wordstr = KDevEditorUtil::currentWord( doc );
}
TQString linestr = KDevEditorUtil::currentLine( doc );
EditorContext context( doc->url(), line, col, linestr, wordstr );
Core::getInstance()->fillContextMenu( popup, &context );
// Remove redundant separators (any that are first, last, or doubled)
bool lastWasSeparator = true;
for( uint i = 0; i < popup->count(); )
{
int id = popup->idAt( i );
if( lastWasSeparator && popup->findItem( id )->isSeparator() )
{
popup->removeItem( id );
// Since we removed an item, don't increment i
} else
{
lastWasSeparator = false;
i++;
}
}
if( lastWasSeparator && popup->count() > 0 )
popup->removeItem( popup->idAt( popup->count() - 1 ) );
}
void EditorProxy::showPopup( )
{
kdDebug(9000) << k_funcinfo << endl;
if ( KParts::Part * part = PartController::getInstance()->activePart() )
{
ViewCursorInterface *iface = dynamic_cast<ViewCursorInterface*>( part->widget() );
if ( iface )
{
KTextEditor::View * view = static_cast<KTextEditor::View*>( part->widget() );
TQPopupMenu * popup = static_cast<TQPopupMenu*>( view->factory()->container("tdetexteditor_popup", view ) );
if ( popup )
{
popup->exec( view->mapToGlobal( iface->cursorCoordinates() ) );
}
}
}
}
void EditorProxy::registerEditor(MultiBuffer* wrapper)
{
m_editorParts.append(wrapper);
}
void EditorProxy::deregisterEditor(MultiBuffer* wrapper)
{
m_editorParts.remove(wrapper);
}
TQWidget * EditorProxy::widgetForPart( KParts::Part * part )
{
if ( !part ) return 0;
if (part->widget())
return part->widget();
KURL url = dynamic_cast<KParts::ReadOnlyPart*>( part )->url();
for (TQValueList<MultiBuffer*>::ConstIterator it = m_editorParts.begin(); it != m_editorParts.end(); ++it)
if ((*it)->hasURL( url ))
return *it;
return 0L;
}
TQWidget * EditorProxy::topWidgetForPart( KParts::Part * part )
{
if ( !part ) return 0;
KURL url = dynamic_cast<KParts::ReadOnlyPart*>( part )->url();
for (TQValueList<MultiBuffer*>::ConstIterator it = m_editorParts.begin(); it != m_editorParts.end(); ++it)
if ((*it)->hasURL( url ))
return *it;
if (part->widget())
return part->widget();
return 0L;
}
bool EditorProxy::isDelayedViewCapable( )
{
return m_delayedViewCreationCompatibleUI;
}
TQWidget *EditorProxy::findPartWidget(KParts::Part *part)
{
for (TQValueList<MultiBuffer*>::ConstIterator it = m_editorParts.begin(); it != m_editorParts.end(); ++it)
if ((*it)->hasPart(part))
return *it;
if (part->widget())
return part->widget();
return 0L;
}
#include "editorproxy.moc"