5#include <tqpopupmenu.h>
10#include <tqradiobutton.h>
11#include <tqcheckbox.h>
17#include <tdeapplication.h>
21#include <tdemessagebox.h>
22#include <tdeparts/part.h>
23#include <tdeparts/factory.h>
24#include <tdeparts/partmanager.h>
25#include <tdeparts/browserextension.h>
26#include <tdefiledialog.h>
27#include <tdemainwindow.h>
29#include <tdemessagebox.h>
30#include <kstatusbar.h>
31#include <tdehtml_part.h>
32#include <tdepopupmenu.h>
33#include <tdeio/netaccess.h>
34#include <kdialogbase.h>
36#include <tdeshortcut.h>
37#include <kcompletion.h>
39#include <tdeversion.h>
40#include <kiconloader.h>
41#include <kuserprofile.h>
42#include <kencodingfiledialog.h>
43#include <ksqueezedtextlabel.h>
45#include <tdetexteditor/view.h>
46#include <tdetexteditor/document.h>
47#include <tdetexteditor/viewcursorinterface.h>
48#include <tdetexteditor/encodinginterface.h>
53#include "editorproxy.h"
54#include "documentationpart.h"
55#include "ksavealldialog.h"
57#include "kdevproject.h"
59#include "mimewarningdialog.h"
61#include "kdevjobtimer.h"
64#include "kdevlanguagesupport.h"
66#include "multibuffer.h"
67#include "partcontroller.h"
74using namespace MainWindowUtils;
81 HistoryEntry(
const KURL& u,
const TQString& c ): url( u ), context( c ) {}
84struct ModificationData
86 KTextEditor::Document * doc;
92PartController::PartController(TQWidget *parent)
93 : KDevPartController(parent), _editorFactory(0L), m_currentActivePart(0), m_removingActivePart(false)
95 connect(
this, TQ_SIGNAL(partRemoved(KParts::Part*)),
this, TQ_SLOT(slotPartRemoved(KParts::Part* )) );
96 connect(
this, TQ_SIGNAL(partAdded(KParts::Part*)),
this, TQ_SLOT(slotPartAdded(KParts::Part* )) );
97 connect(
this, TQ_SIGNAL(activePartChanged(KParts::Part*)),
this, TQ_SLOT(slotActivePartChanged(KParts::Part*)));
103 m_openNextAsText =
false;
107PartController::~PartController()
112void PartController::createInstance(TQWidget *parent)
125void PartController::setupActions()
129 TDEAction* newAction = KStdAction::open(
this, TQ_SLOT(slotOpenFile()), ac,
"file_open");
130 newAction->setToolTip( i18n(
"Open file") );
131 newAction->setWhatsThis( i18n(
"<b>Open file</b><p>Opens an existing file without adding it to the project.</p>") );
133 m_openRecentAction = KStdAction::openRecent(
this, TQ_SLOT(slotOpenRecent(
const KURL&) ), ac,
"file_open_recent" );
134 m_openRecentAction->setWhatsThis(TQString(
"<b>%1</b><p>%2").arg(beautifyToolTip(m_openRecentAction->text())).arg(i18n(
"Opens recently opened file.")));
135 m_openRecentAction->loadEntries( kapp->config(),
"RecentFiles" );
137 m_saveAllFilesAction =
new TDEAction(i18n(
"Save Al&l"), 0,
this, TQ_SLOT(slotSaveAllFiles()), ac,
"file_save_all");
138 m_saveAllFilesAction->setToolTip( i18n(
"Save all modified files") );
139 m_saveAllFilesAction->setWhatsThis(i18n(
"<b>Save all</b><p>Saves all modified files."));
140 m_saveAllFilesAction->setEnabled(
false);
142 m_revertAllFilesAction =
new TDEAction(i18n(
"Rever&t All"), 0,
this, TQ_SLOT(slotRevertAllFiles()), ac,
"file_revert_all");
143 m_revertAllFilesAction->setToolTip(i18n(
"Revert all changes"));
144 m_revertAllFilesAction->setWhatsThis(i18n(
"<b>Revert all</b><p>Reverts all changes in opened files. Prompts to save changes so the reversion can be canceled for each modified file."));
145 m_revertAllFilesAction->setEnabled(
false);
147 m_closeWindowAction = KStdAction::close(
this, TQ_SLOT(slotCloseWindow()), ac,
"file_close");
148 m_closeWindowAction->setToolTip( i18n(
"Close current file") );
149 m_closeWindowAction->setWhatsThis(TQString(
"<b>%1</b><p>%2").arg(beautifyToolTip(m_closeWindowAction->text())).arg(i18n(
"Closes current file.")));
150 m_closeWindowAction->setEnabled(
false);
152 m_closeAllWindowsAction =
new TDEAction(i18n(
"Close All"), 0,
this, TQ_SLOT(slotCloseAllWindows()), ac,
"file_close_all");
153 m_closeAllWindowsAction->setToolTip( i18n(
"Close all files") );
154 m_closeAllWindowsAction->setWhatsThis(i18n(
"<b>Close all</b><p>Close all opened files."));
155 m_closeAllWindowsAction->setEnabled(
false);
157 m_closeOtherWindowsAction =
new TDEAction(i18n(
"Close All Others"), 0,
this, TQ_SLOT(slotCloseOtherWindows()), ac,
"file_closeother");
158 m_closeOtherWindowsAction->setToolTip( i18n(
"Close other files") );
159 m_closeOtherWindowsAction->setWhatsThis(i18n(
"<b>Close all others</b><p>Close all opened files except current."));
160 m_closeOtherWindowsAction->setEnabled(
false);
162 new TDEActionSeparator(ac,
"dummy_separator");
164 m_backAction =
new TDEToolBarPopupAction(i18n(
"Back"),
"back", 0,
this, TQ_SLOT(slotBack()), ac,
"history_back");
165 m_backAction->setEnabled(
false );
166 m_backAction->setToolTip(i18n(
"Back"));
167 m_backAction->setWhatsThis(i18n(
"<b>Back</b><p>Moves backwards one step in the navigation history."));
168 connect(m_backAction->popupMenu(), TQ_SIGNAL(aboutToShow()),
this, TQ_SLOT(slotBackAboutToShow()));
169 connect(m_backAction->popupMenu(), TQ_SIGNAL(activated(
int)),
this, TQ_SLOT(slotBackPopupActivated(
int)));
171 m_forwardAction =
new TDEToolBarPopupAction(i18n(
"Forward"),
"forward", 0,
this, TQ_SLOT(slotForward()), ac,
"history_forward");
172 m_forwardAction->setEnabled(
false );
173 m_forwardAction->setToolTip(i18n(
"Forward"));
174 m_forwardAction->setWhatsThis(i18n(
"<b>Forward</b><p>Moves forward one step in the navigation history."));
175 connect(m_forwardAction->popupMenu(), TQ_SIGNAL(aboutToShow()),
this, TQ_SLOT(slotForwardAboutToShow()));
176 connect(m_forwardAction->popupMenu(), TQ_SIGNAL(activated(
int)),
this, TQ_SLOT(slotForwardPopupActivated(
int)));
178 m_gotoLastEditPosAction =
new TDEAction( i18n(
"Goto Last Edit Position"),
"go-bottom", 0,
this, TQ_SLOT(gotoLastEditPos()), ac,
"goto_last_edit_pos" );
179 m_gotoLastEditPosAction->setEnabled(
false );
180 m_gotoLastEditPosAction->setToolTip( i18n(
"Goto Last Edit Position") );
181 m_gotoLastEditPosAction->setWhatsThis( i18n(
"<b>Goto Last Edit Position</b><p>Open the last edited file and position cursor at the point of edit") );
184void PartController::setEncoding(
const TQString &encoding)
186 m_presetEncoding = encoding;
189KParts::Part* PartController::findOpenDocument(
const KURL& url)
192 KParts::Part * part = partForURL( url );
199 if ( API::getInstance()->project() )
201 KURL partURL = findURLInProject( url );
203 return partForURL( partURL );
209KURL PartController::findURLInProject(
const KURL& url)
211 TQStringList fileList = API::getInstance()->project()->allFiles();
213 bool filenameOnly = (url.url().find(
'/') == -1);
214 TQString filename = filenameOnly ?
"/" :
"";
215 filename += url.url();
217 for (TQStringList::Iterator it = fileList.begin(); it != fileList.end(); ++it) {
218 if ((*it).endsWith(filename)) {
220 return KURL( API::getInstance()->project()->projectDirectory() +
"/" + *it );
227void PartController::editDocument(
const KURL &inputUrl,
int lineNum,
int col)
229 editDocumentInternal(inputUrl, lineNum, col);
232void PartController::splitCurrentDocument(
const KURL &inputUrl,
233 int lineNum,
int col)
235 editDocumentInternal(inputUrl, lineNum, col,
true,
true);
238void PartController::scrollToLineColumn(
const KURL &inputUrl,
239 int lineNum,
int col,
bool storeHistory )
241 if ( KParts::ReadOnlyPart *existingPart = partForURL( inputUrl ) )
243 if( storeHistory ) addHistoryEntry( existingPart );
244 EditorProxy::getInstance()->setLineNumber( existingPart, lineNum, col );
249void PartController::editDocumentInternal(
const KURL & inputUrl,
int lineNum,
250 int col,
bool activate,
251 bool addToCurrentBuffer )
253 kdDebug(9000) << k_funcinfo <<
"\n " << inputUrl.prettyURL()
254 <<
" linenum " << lineNum <<
" activate? " << activate
255 <<
" addToCurrentBuffer? " << addToCurrentBuffer << endl;
261 if ( KParts::Part *existingPart = partForURL( url ) )
264 if ( !m_presetEncoding.isNull() )
266 if ( KTextEditor::EncodingInterface * ei =
dynamic_cast<KTextEditor::EncodingInterface*
>( existingPart ) )
268 ei->setEncoding( m_presetEncoding );
270 m_presetEncoding = TQString();
274 activatePart( existingPart );
275 EditorProxy::getInstance()->setLineNumber( existingPart, lineNum, col );
280 if ( !url.isValid() || !TDEIO::NetAccess::exists(url,
false, 0) )
285 if ( API::getInstance()->project() )
287 if (url.isRelativeURL(url.url())) {
288 KURL relURL(API::getInstance()->project()->projectDirectory());
289 relURL.addPath( url.url() );
291 kdDebug() << k_funcinfo <<
"Looking for file in project dir: " << API::getInstance()->project()->projectDirectory() <<
" url " << url.url() <<
" transformed to " << relURL.url() <<
": " << done << endl;
292 if (relURL.isValid() && TDEIO::NetAccess::exists(relURL,
false, 0)) {
297 KURL relURL(API::getInstance()->project()->buildDirectory());
298 relURL.addPath( url.url() );
299 kdDebug() << k_funcinfo <<
"Looking for file in build dir: " << API::getInstance()->project()->buildDirectory() <<
" url " << url.url() <<
" transformed to " << relURL.url() <<
": " << done << endl;
300 if (relURL.isValid() && TDEIO::NetAccess::exists(relURL,
false, 0)) {
308 url = findURLInProject(url);
310 if ( !url.isValid() || !TDEIO::NetAccess::exists(url,
false, 0) )
312 url = API::getInstance()->project()->projectDirectory() +
"/" + url.path();
319 if ( !done && ( !url.isValid() || !TDEIO::NetAccess::exists(url,
false, 0) ))
322 kdDebug(9000) <<
"cannot find URL: " << url.url() << endl;
331 if (url.isLocalFile())
333 TQString path = url.path();
334 path = URLUtil::canonicalPath(path);
335 if ( !path.isEmpty() )
340 KParts::Part *existingPart = partForURL(url);
344 activatePart(existingPart);
345 EditorProxy::getInstance()->setLineNumber(existingPart, lineNum, col);
349 if ( !addToCurrentBuffer )
351 if ( KDevLanguageSupport *lang =
352 API::getInstance()->languageSupport() )
356 addToCurrentBuffer = lang->shouldSplitDocument( inputUrl );
358 if ( addToCurrentBuffer )
361 "languagePart() insists addToCurrentBuffer = true" << endl;
370 KMimeType::Ptr MimeType = KMimeType::findByURL( url );
372 kdDebug(9000) <<
"mimeType = " << MimeType->name() << endl;
375 if ( MimeType->is(
"inode/directory" ) )
380 if ( !m_presetEncoding.isNull() )
382 m_openNextAsText =
true;
385 TDEConfig *config = kapp->config();
386 config->setGroup(
"General Options");
389 if ( !m_openNextAsText && MimeType->is(
"application/x-designer" ) )
391 TQString DesignerSetting = config->readEntry(
"DesignerSetting",
"ExternalDesigner" );
392 TQString designerExec =
"designer";
393 TQStringList designerPluginPaths;
394 TQDomDocument* dom = API::getInstance()->projectDom();
399 DesignerSetting = DomUtil::readEntry(*dom,
"/kdevcppsupport/qt/designerintegration", DesignerSetting );
400 designerExec = DomUtil::readEntry(*dom,
"/kdevcppsupport/qt/designer", designerExec );
402 if ( DesignerSetting ==
"ExternalKDevDesigner" )
404 designerExec =
"kdevdesigner";
406 else if ( DesignerSetting ==
"EmbeddedKDevDesigner" )
408 if ( KParts::ReadOnlyPart *designerPart = qtDesignerPart() )
411 activatePart(designerPart);
412 designerPart->openURL(url);
415 else if ( KParts::Factory * KDevDesignerFactory =
static_cast<KParts::Factory*
>( KLibLoader::self()->factory( TQFile::encodeName(
"libkdevdesignerpart" ) ) ) )
417 KParts::ReadWritePart * kdevpart =
static_cast<KParts::ReadWritePart*
>( KDevDesignerFactory->createPart(
TopLevel::getInstance()->main(), 0, 0, 0,
"KParts::ReadWritePart" ) );
418 kdevpart->openURL( url );
420 integratePart( kdevpart, url );
421 m_openRecentAction->addURL( url );
422 m_openRecentAction->saveEntries( kapp->config(),
"RecentFiles" );
427 if( designerPluginPaths.isEmpty() )
428 KRun::runCommand( designerExec+
" "+url.pathOrURL() );
430 KRun::runCommand(
"TQT_PLUGIN_PATH=\""+designerPluginPaths.join(
":")+
"\" "+designerExec+
" "+url.pathOrURL() );
435 config->setGroup(
"General");
437 TQStringList texttypeslist = config->readListEntry(
"TextTypes" );
438 if ( texttypeslist.contains( MimeType->name() ) )
440 m_openNextAsText =
true;
444 TQVariant v = MimeType->property(
"X-TDE-text");
448 if ( m_openNextAsText || isText || MimeType->is(
"application/x-zerosize" ) )
450 KTextEditor::Editor *editorpart =
451 createEditorPart( activate, addToCurrentBuffer, url );
454 if ( m_presetEncoding.isNull() && API::getInstance()->projectDom() )
456 TQDomDocument * projectDom = API::getInstance()->projectDom();
457 m_presetEncoding = DomUtil::readEntry( *projectDom,
"/general/defaultencoding", TQString() );
460 if ( !m_presetEncoding.isNull() )
462 if ( KTextEditor::EncodingInterface * ei =
dynamic_cast<KTextEditor::EncodingInterface*
>( editorpart ) )
464 ei->setEncoding( m_presetEncoding );
466 m_presetEncoding = TQString();
471 TQWidget * widget = EditorProxy::getInstance()->topWidgetForPart( editorpart );
473 integratePart(editorpart, url, widget,
true, activate, addToCurrentBuffer);
474 EditorProxy::getInstance()->setLineNumber(editorpart, lineNum, col);
476 m_openNextAsText =
false;
478 m_openRecentAction->addURL( url );
479 m_openRecentAction->saveEntries( kapp->config(),
"RecentFiles" );
487 KParts::Factory *factory = 0;
490 TQString services[] = {
"KParts/ReadWritePart",
"KParts/ReadOnlyPart" };
491 TQString classnames[] = {
"KParts::ReadWritePart",
"KParts::ReadOnlyPart" };
492 for (uint i=0; i<2; ++i)
494 factory = findPartFactory( MimeType->name(), services[i] );
497 className = classnames[i];
502 kdDebug(9000) <<
"factory = " << factory << endl;
507 KParts::ReadOnlyPart *part =
static_cast<KParts::ReadOnlyPart*
>( factory->createPart(
TopLevel::getInstance()->main(), 0, 0, 0, className.latin1() ) );
510 part->openURL( url );
513 if (
dynamic_cast<KTextEditor::Editor*
>( part ) )
515 integratePart(part, url, part->widget(),
true, activate);
516 EditorProxy::getInstance()->setLineNumber(part, lineNum, col);
520 integratePart( part, url );
523 m_openRecentAction->addURL( url );
524 m_openRecentAction->saveEntries( kapp->config(),
"RecentFiles" );
529 MimeWarningDialog dlg;
530 dlg.text2->setText( TQString(
"<qt><b>%1</b></qt>" ).arg(url.path()));
531 dlg.text3->setText( dlg.text3->text().arg(MimeType->name()) );
533 if ( dlg.exec() == TQDialog::Accepted )
535 if ( dlg.open_with_kde->isChecked() )
537 KRun::runURL(url, MimeType->name() );
541 if ( dlg.always_open_as_text->isChecked() )
543 TDEConfig *config = kapp->config();
544 config->setGroup(
"General");
545 TQStringList texttypeslist = config->readListEntry(
"TextTypes" );
546 texttypeslist << MimeType->name();
547 config->writeEntry(
"TextTypes", texttypeslist );
549 m_openNextAsText =
true;
550 editDocument( url, lineNum, col );
557void PartController::showDocument(
const KURL &url,
bool newWin)
559 TQString fixedPath = HTMLDocumentationPart::resolveEnvVarsInURL(url.url());
560 KURL docUrl(fixedPath);
561 kdDebug(9000) <<
"SHOW: " << docUrl.url() << endl;
563 if ( docUrl.isLocalFile() && KMimeType::findByURL(docUrl)->name() !=
"text/html" ) {
566 editDocument( docUrl );
576 integratePart(part,docUrl);
577 connect(part, TQ_SIGNAL(fileNameChanged(KParts::ReadOnlyPart* )),
578 this, TQ_SIGNAL(partURLChanged(KParts::ReadOnlyPart* )));
584 part->openURL(docUrl);
587KParts::Factory *PartController::findPartFactory(
const TQString &mimeType,
const TQString &partType,
const TQString &preferredName)
589 TDETrader::OfferList offers = TDETrader::self()->query(mimeType, TQString(
"'%1' in ServiceTypes").arg(partType));
591 if (offers.count() > 0)
593 KService::Ptr ptr = 0;
595 if ( !preferredName.isEmpty() ) {
596 TDETrader::OfferList::Iterator it;
597 for (it = offers.begin(); it != offers.end(); ++it) {
598 if ((*it)->desktopEntryName() == preferredName) {
605 ptr = offers.first();
607 return static_cast<KParts::Factory*
>(KLibLoader::self()->factory(TQFile::encodeName(ptr->library())));
613KTextEditor::Editor * PartController::createEditorPart(
bool activate,
614 bool addToCurrentBuffer,
617 MultiBuffer *multiBuffer = 0;
618 if ( addToCurrentBuffer )
621 dynamic_cast<MultiBuffer*
>(
622 EditorProxy::getInstance()->topWidgetForPart( activePart() )
627 kdDebug(9000) <<
"Creating a new MultiBuffer for "
628 << url.fileName() << endl;
632 static bool alwaysActivate =
true;
634 kapp->config()->setGroup(
"Editor");
635 TQString preferred = kapp->config()->readPathEntry(
"EmbeddedKTextEditor");
639 if ( preferred !=
"kyzispart" )
640 alwaysActivate =
false;
642 KTextEditor::Editor *editorpart =
643 dynamic_cast<KTextEditor::Editor*
>(multiBuffer->createPart(
"text/plain",
644 "KTextEditor/Document",
645 alwaysActivate | activate ?
646 "KTextEditor::Editor" :
"KTextEditor::Document",
651 editorpart->openURL( url );
653 multiBuffer->registerURL( url, editorpart );
654 multiBuffer->setDelayedActivation( !activate );
658void PartController::integratePart(KParts::Part *part,
const KURL &url,
659 TQWidget* widget,
bool isTextEditor,
660 bool activate,
bool addToCurrentBuffer )
662 if (!widget) widget = part->widget();
666 kdDebug(9000) <<
"no widget for this part!!" << endl;
670 if ( !addToCurrentBuffer )
673 addPart(part, activate);
676 KParts::ReadOnlyPart *ro_part =
dynamic_cast<KParts::ReadOnlyPart*
>(part);
677 if ( !ro_part )
return;
679 emit loadedFile( ro_part->url() );
681 connect( part, TQ_SIGNAL(modifiedOnDisc(Kate::Document*,
bool,
unsigned char)),
this, TQ_SLOT(slotDocumentDirty(Kate::Document*,
bool,
unsigned char)) );
684 connect(part, TQ_SIGNAL(completed()),
this, TQ_SLOT(slotUploadFinished()));
694 integrateTextEditorPart(
static_cast<KTextEditor::Document*
>(part));
696 KInterfaceDesigner::Designer *designerPart =
dynamic_cast<KInterfaceDesigner::Designer *
>(part);
697 if (designerPart && API::getInstance()->languageSupport())
699 kdDebug() <<
"integrating designer part with language support" << endl;
700 connect(designerPart, TQ_SIGNAL(addedFunction(DesignerType,
const TQString&, Function )),
701 API::getInstance()->languageSupport(),
702 TQ_SLOT(addFunction(DesignerType,
const TQString&, Function )));
703 connect(designerPart, TQ_SIGNAL(editedFunction(DesignerType,
const TQString&, Function, Function )), API::getInstance()->languageSupport(),
704 TQ_SLOT(editFunction(DesignerType,
const TQString&, Function, Function )));
705 connect(designerPart, TQ_SIGNAL(removedFunction(DesignerType,
const TQString&, Function )),
706 API::getInstance()->languageSupport(),
707 TQ_SLOT(removeFunction(DesignerType,
const TQString&, Function )));
708 connect(designerPart, TQ_SIGNAL(editFunction(DesignerType,
const TQString&,
const TQString& )),
709 API::getInstance()->languageSupport(),
710 TQ_SLOT(openFunction(DesignerType,
const TQString&,
const TQString& )));
711 connect(designerPart, TQ_SIGNAL(editSource(DesignerType,
const TQString& )),
712 API::getInstance()->languageSupport(),
713 TQ_SLOT(openSource(DesignerType,
const TQString& )));
714 connect(designerPart, TQ_SIGNAL(newStatus(
const TQString &,
int)),
715 this, TQ_SLOT(slotNewDesignerStatus(
const TQString &,
int)));
719void PartController::integrateTextEditorPart(KTextEditor::Document* doc)
736 connect( doc, TQ_SIGNAL(textChanged()),
this, TQ_SLOT(textChanged()) );
737 connect( doc, TQ_SIGNAL(fileNameChanged()),
738 this, TQ_SLOT(slotDocumentUrlChanged()));
742 connect( doc->widget(), TQ_SIGNAL(dropEventPass(TQDropEvent *)),
746 if ( KTextEditor::View * view =
dynamic_cast<KTextEditor::View*
>( doc->widget() ) )
748 TDEActionCollection* c = view->actionCollection();
752 if (TDEAction* a = c->action(
"view_folding_markers"))
754 if (a->shortcut() == TDEShortcut(Key_F9))
755 a->setShortcut(TDEShortcut());
758 if (TDEAction* a = c->action(
"view_dynamic_word_wrap"))
760 if (a->shortcut() == TDEShortcut(Key_F10))
761 a->setShortcut(TDEShortcut());
764 if (TDEAction* a = c->action(
"view_line_numbers"))
766 if (a->shortcut() == TDEShortcut(Key_F11))
767 a->setShortcut(TDEShortcut());
779 TQPtrList<KTextEditor::View> list = doc->views();
780 TQPtrListIterator<KTextEditor::View> it( list );
781 while ( it.current() )
783 connect( it, TQ_SIGNAL( newStatus() ),
this, TQ_SLOT( slotNewStatus() ) );
788void PartController::slotPartAdded( KParts::Part * part )
790 kdDebug(9000) << k_funcinfo << endl;
792 if ( KParts::ReadOnlyPart * ro_part =
dynamic_cast<KParts::ReadOnlyPart*
>( part ) )
794 updatePartURL( ro_part );
800void PartController::slotPartRemoved( KParts::Part * part )
802 kdDebug(9000) << k_funcinfo << endl;
804 _partURLMap.remove(
static_cast<KParts::ReadOnlyPart*
>(part) );
806 if ( part == m_currentActivePart )
808 m_removingActivePart =
true;
814void PartController::updatePartURL( KParts::ReadOnlyPart * ro_part )
816 if ( ro_part->url().isEmpty() )
818 kdDebug(9000) <<
"updatePartURL() called with empty URL for part: " << ro_part << endl;
821 _partURLMap[ ro_part ] = ro_part->url();
824bool PartController::partURLHasChanged( KParts::ReadOnlyPart * ro_part )
826 if ( _partURLMap.contains( ro_part ) && !ro_part->url().isEmpty() )
828 if ( _partURLMap[ ro_part ] != ro_part->url() )
836KURL PartController::storedURLForPart( KParts::ReadOnlyPart * ro_part )
838 if ( _partURLMap.contains( ro_part ) )
840 return _partURLMap[ ro_part ];
846void PartController::slotUploadFinished()
848 KParts::ReadOnlyPart *ro_part =
const_cast<KParts::ReadOnlyPart*
>(
dynamic_cast<const KParts::ReadOnlyPart*
>(sender()) );
849 if ( !ro_part )
return;
851 if ( partURLHasChanged( ro_part ) )
853 emit partURLChanged( ro_part );
854 updatePartURL( ro_part );
858KParts::ReadOnlyPart *PartController::partForURL(
const KURL &url)
860 TQPtrListIterator<KParts::Part> it(*parts());
861 for ( ; it.current(); ++it)
863 KParts::ReadOnlyPart *ro_part =
dynamic_cast<KParts::ReadOnlyPart*
>(it.current());
864 if (ro_part && url.path() == ro_part->url().path())
870KParts::Part * PartController::partForWidget(
const TQWidget * widget )
872 TQPtrListIterator<KParts::Part> it(*parts());
873 for ( ; it.current(); ++it)
875 if ( it.current()->widget() == widget )
884void PartController::activatePart(KParts::Part *part)
888 TQWidget * widget = EditorProxy::getInstance()->widgetForPart( part );
898 TQWidget* w2 = EditorProxy::getInstance()->widgetForPart( part );
903bool PartController::closePart(KParts::Part *part)
905 KParts::ReadOnlyPart * ro_part =
906 dynamic_cast<KParts::ReadOnlyPart*
>( part );
908 if ( !ro_part )
return true;
910 KURL url = ro_part->url();
912 if (TQWidget* w = EditorProxy::getInstance()->topWidgetForPart( part ) )
914 if ( MultiBuffer *multiBuffer =
dynamic_cast<MultiBuffer*
>( w ) )
916 kdDebug(9000) <<
"About to delete MultiBuffered document..."
917 <<
" numberOfBuffers: " << multiBuffer->numberOfBuffers()
918 <<
" isActivated: " << multiBuffer->isActivated()
920 if ( !multiBuffer->closeURL( url ) )
923 if ( multiBuffer->numberOfBuffers() == 0
924 || !multiBuffer->isActivated() )
927 _dirtyDocuments.remove(
static_cast<KParts::ReadWritePart*
>( ro_part ) );
928 emit closedFile( url );
933 multiBuffer->deleteLater();
939 _dirtyDocuments.remove(
static_cast<KParts::ReadWritePart*
>( ro_part ) );
941 emit closedFile( url );
944 setActivePart( multiBuffer->activeBuffer() );
948 else if ( !ro_part->closeURL() )
952 else if ( !ro_part->closeURL() )
956 _dirtyDocuments.remove(
static_cast<KParts::ReadWritePart*
>( ro_part ) );
957 emit closedFile( url );
965void PartController::updateMenuItems()
967 bool hasWriteParts =
false;
968 bool hasReadOnlyParts =
false;
970 TQPtrListIterator<KParts::Part> it(*parts());
971 for ( ; it.current(); ++it)
973 if (it.current()->inherits(
"KParts::ReadWritePart"))
974 hasWriteParts =
true;
975 if (it.current()->inherits(
"KParts::ReadOnlyPart"))
976 hasReadOnlyParts =
true;
979 m_saveAllFilesAction->setEnabled(hasWriteParts);
980 m_revertAllFilesAction->setEnabled(hasWriteParts);
981 m_closeWindowAction->setEnabled(hasReadOnlyParts);
982 m_closeAllWindowsAction->setEnabled(hasReadOnlyParts);
983 m_closeOtherWindowsAction->setEnabled(hasReadOnlyParts);
985 m_backAction->setEnabled( !m_backHistory.isEmpty() );
988void PartController::slotRevertAllFiles()
993void PartController::reloadFile(
const KURL & url )
995 KParts::ReadWritePart * part =
dynamic_cast<KParts::ReadWritePart*
>( partForURL( url ) );
998 if ( part->isModified() )
1001 i18n(
"The file \"%1\" is modified in memory. Are you sure you want to reload it? (Local changes will be lost.)" ).arg( url.path() ),
1002 i18n(
"File is Modified" ), i18n(
"Reload"), i18n(
"Do Not Reload") ) == KMessageBox::Yes )
1004 part->setModified(
false );
1012 unsigned int line = 0;
unsigned int col = 0;
1013 KTextEditor::ViewCursorInterface * iface =
dynamic_cast<KTextEditor::ViewCursorInterface*
>( part->widget() );
1016 iface->cursorPositionReal( &line, &col );
1019 part->openURL( url );
1021 _dirtyDocuments.remove( part );
1022 emit documentChangedState( url, Clean );
1026 iface->setCursorPositionReal( line, col );
1031void PartController::revertFiles(
const KURL::List & list )
1033 KURL::List::ConstIterator it = list.begin();
1034 while ( it != list.end() )
1041void PartController::revertAllFiles()
1043 revertFiles( openURLs() );
1046void PartController::slotCloseWindow()
1048 closePart( activePart() );
1051KURL::List PartController::modifiedDocuments()
1053 KURL::List modFiles;
1055 TQPtrListIterator<KParts::Part> it( *parts() );
1056 while( it.current() )
1058 KParts::ReadWritePart *rw_part =
dynamic_cast<KParts::ReadWritePart*
>(it.current());
1059 if ( rw_part && rw_part->isModified() )
1061 modFiles << rw_part->url();
1068void PartController::slotSave()
1070 kdDebug(9000) << k_funcinfo << endl;
1072 if ( KParts::ReadWritePart * part =
dynamic_cast<KParts::ReadWritePart*
>( activePart() ) )
1074 saveFile( part->url() );
1078void PartController::slotReload()
1080 kdDebug(9000) << k_funcinfo << endl;
1082 if ( KParts::ReadWritePart * part =
dynamic_cast<KParts::ReadWritePart*
>( activePart() ) )
1084 reloadFile( part->url() );
1088void PartController::slotSaveAllFiles()
1093bool PartController::saveFile(
const KURL & url,
bool force )
1095 KParts::ReadWritePart * part =
dynamic_cast<KParts::ReadWritePart*
>( partForURL( url ) );
1096 if ( !part )
return true;
1098 switch( documentState( url ) )
1105 kdDebug(9000) <<
"Forced save" << endl;
1109 kdDebug(9000) <<
"Normal save" << endl;
1113 case DirtyAndModified:
1116 i18n(
"The file \"%1\" is modified on disk.\n\nAre you sure you want to overwrite it? (External changes will be lost.)").arg( url.path() ),
1117 i18n(
"File Externally Modified"), i18n(
"Overwrite"), i18n(
"Do Not Overwrite") );
1118 if ( code == KMessageBox::Yes )
1120 kdDebug(9000) <<
"Dirty save!!" << endl;
1122 else if ( code == KMessageBox::No )
1139 _dirtyDocuments.remove( part );
1140 emit documentChangedState( url, Clean );
1141 emit savedFile( url );
1147bool PartController::saveAllFiles()
1149 return saveFiles( openURLs() );
1152bool PartController::saveFiles( KURL::List
const & filelist )
1154 KURL::List::ConstIterator it = filelist.begin();
1155 while ( it != filelist.end() )
1157 if (saveFile( *it )==
false)
1164bool PartController::querySaveFiles()
1166 return saveFilesDialog( KURL::List() );
1169void PartController::clearModified( KURL::List
const & filelist )
1171 KURL::List::ConstIterator it = filelist.begin();
1172 while ( it != filelist.end() )
1174 KParts::ReadWritePart * rw_part =
dynamic_cast<KParts::ReadWritePart*
>( partForURL( *it ) );
1177 rw_part->setModified(
false );
1183bool PartController::saveFilesDialog( KURL::List
const & ignoreList )
1185 KURL::List modList = modifiedDocuments();
1187 if ( modList.count() > 0 && modList != ignoreList )
1190 if ( dlg.exec() == TQDialog::Accepted )
1192 saveFiles( dlg.filesToSave() );
1193 clearModified( dlg.filesNotToSave() );
1203bool PartController::closeFilesDialog( KURL::List
const & ignoreList )
1205 if ( !saveFilesDialog( ignoreList ) )
return false;
1207 TQPtrList<KParts::Part> partList( *parts() );
1208 TQPtrListIterator<KParts::Part> it( partList );
1209 while ( KParts::Part* part = it.current() )
1211 KParts::ReadOnlyPart * ro_part =
dynamic_cast<KParts::ReadOnlyPart*
>( part );
1212 if ( ro_part && !ignoreList.contains( ro_part->url() ) || !ro_part )
1221bool PartController::closeFiles(
const KURL::List & list )
1223 KURL::List::ConstIterator it = list.begin();
1224 while ( it != list.end() )
1226 if ( !closePart( partForURL( *it ) ) )
1235bool PartController::closeFile(
const KURL & url )
1237 return closePart( partForURL( url ) );
1240bool PartController::closeAllFiles()
1242 return closeFilesDialog( KURL::List() );
1245void PartController::slotCloseAllWindows()
1250bool PartController::closeAllOthers(
const KURL & url )
1252 KURL::List ignoreList;
1253 ignoreList.append( url );
1255 return closeFilesDialog( ignoreList );
1259void PartController::slotCloseOtherWindows()
1261 if ( KParts::ReadOnlyPart * active =
dynamic_cast<KParts::ReadOnlyPart*
>( activePart() ) )
1263 closeAllOthers( active->url() );
1267void PartController::slotOpenFile()
1269 TQString DefaultEncoding;
1270 if ( TQDomDocument * projectDom = API::getInstance()->projectDom() )
1272 DefaultEncoding = DomUtil::readEntry( *projectDom,
"/general/defaultencoding", TQString() );
1275 if ( DefaultEncoding.isEmpty() )
1278 TDEConfig * config = kapp->config();
1279 config->setGroup(
"Kate Document Defaults");
1280 DefaultEncoding = config->readEntry(
"Encoding", TQString() );
1283 KEncodingFileDialog::Result result = KEncodingFileDialog::getOpenURLsAndEncoding( DefaultEncoding, TQString(),
1286 for ( KURL::List::Iterator it = result.URLs.begin(); it != result.URLs.end(); ++it )
1288 m_presetEncoding = result.encoding;
1289 editDocument( *it );
1293void PartController::slotOpenRecent(
const KURL& url )
1295 editDocument( url );
1297 m_openRecentAction->setCurrentItem( -1 );
1300bool PartController::readyToClose()
1302 blockSignals(
true );
1309void PartController::slotActivePartChanged( KParts::Part *part )
1311 kdDebug(9000) << k_funcinfo << part << endl;
1313 if ( !m_isJumping && !m_removingActivePart )
1315 if ( KParts::ReadOnlyPart * ro_part =
dynamic_cast<KParts::ReadOnlyPart*
>(m_currentActivePart) )
1317 addHistoryEntry( ro_part );
1321 m_currentActivePart = part;
1322 m_removingActivePart =
false;
1325 KXMLGUIClient* client =
dynamic_cast<KXMLGUIClient*
>(part->widget());
1330 TQTimer::singleShot( 100,
this, TQ_SLOT(slotWaitForFactoryHack()) );
1335 if (!part->widget()) {
1340 TQPtrListIterator<KParts::Part> it(*parts());
1341 for ( ; it.current(); ++it)
1343 if( it.current() == part ){
1345 activatePart( it.current() );
1355void PartController::slotDocumentDirty( Kate::Document * d,
bool isModified,
unsigned char reason )
1357 kdDebug(9000) << k_funcinfo << endl;
1360 KTextEditor::Document * doc = 0;
1362 TQPtrListIterator<KParts::Part> it( *parts() );
1363 while( it.current() )
1365 if ( (
void*)it.current() == (
void*)d )
1367 doc =
dynamic_cast<KTextEditor::Document*
>( it.current() );
1378 ModificationData * p =
new ModificationData;
1380 p->isModified = isModified;
1382 KDevJobTimer::singleShot( 0,
this, TQ_SLOT(slotDocumentDirtyStepTwo(
void*)), p );
1386void PartController::slotDocumentDirtyStepTwo(
void * payload )
1388 if ( !payload )
return;
1390 ModificationData * p =
reinterpret_cast<ModificationData*
>( payload );
1391 KTextEditor::Document * doc = p->doc;
1394 bool haveDocument =
false;
1395 if(
const TQPtrList<KParts::Part> * partlist = parts() )
1397 TQPtrListIterator<KParts::Part> it( *partlist );
1398 while ( KParts::Part * part = it.current() )
1400 if ( p->doc ==
dynamic_cast<KTextEditor::Document*
>( part ) )
1402 haveDocument =
true;
1408 if ( !haveDocument )
return;
1410 bool isModified = p->isModified;
1411 unsigned char reason = p->reason;
1414 KURL url = storedURLForPart( doc );
1415 if ( url.isEmpty() )
1417 kdDebug(9000) <<
"Warning!! the stored url is empty. Bailing out!" << endl;
1422 if ( !_dirtyDocuments.contains( doc ) )
1424 _dirtyDocuments.append( doc );
1427 if ( reactToDirty( url, reason ) )
1430 emit documentChangedState( url, Clean );
1431 _dirtyDocuments.remove( doc );
1440 _dirtyDocuments.remove( doc );
1441 emit documentChangedState( url, Clean );
1444 kdDebug(9000) << doc->url().url() << endl;
1445 kdDebug(9000) << isModified << endl;
1446 kdDebug(9000) << reason << endl;
1449bool PartController::isDirty( KURL
const & url )
1451 return _dirtyDocuments.contains(
static_cast<KTextEditor::Document*
>( partForURL( url ) ) );
1454bool PartController::reactToDirty( KURL
const & url,
unsigned char reason )
1456 TDEConfig *config = kapp->config();
1457 config->setGroup(
"Editor");
1458 TQString dirtyAction = config->readEntry(
"DirtyAction" );
1460 if ( dirtyAction ==
"nothing" )
return false;
1462 bool isModified =
true;
1463 if( KParts::ReadWritePart * part =
dynamic_cast<KParts::ReadWritePart*
>( partForURL( url ) ) )
1465 isModified = part->isModified();
1469 kdDebug(9000) << k_funcinfo <<
" Warning. Not a ReadWritePart." << endl;
1476 i18n(
"Conflict: The file \"%1\" has changed on disk while being modified in memory.\n\n"
1477 "You should investigate before saving to make sure you are not losing data.").arg( url.path() ),
1485 i18n(
"Warning: The file \"%1\" has been deleted on disk.\n\n"
1486 "If this was not your intention, make sure to save this file now.").arg( url.path() ),
1487 i18n(
"File Deleted") );
1491 if ( dirtyAction ==
"alert" )
1494 i18n(
"The file \"%1\" has changed on disk.\n\nDo you want to reload it?").arg( url.path() ),
1495 i18n(
"File Changed"), i18n(
"Reload"), i18n(
"Do Not Reload") ) == KMessageBox::No )
1507void PartController::slotNewDesignerStatus(
const TQString &formName,
int status)
1509 kdDebug(9000) << k_funcinfo << endl;
1510 kdDebug(9000) <<
" formName: " << formName <<
", status: " << status << endl;
1511 emit documentChangedState( KURL::fromPathOrURL(formName), DocumentState(status) );
1514void PartController::slotNewStatus( )
1516 kdDebug(9000) << k_funcinfo << endl;
1518 TQObject * senderobj =
const_cast<TQObject*
>(sender());
1519 KTextEditor::View * view =
dynamic_cast<KTextEditor::View*
>( senderobj );
1522 doEmitState( view->document()->url() );
1526DocumentState PartController::documentState( KURL
const & url )
1528 KParts::ReadWritePart * rw_part =
dynamic_cast<KParts::ReadWritePart*
>( partForURL( url ) );
1529 if ( !rw_part )
return Clean;
1531 DocumentState state = Clean;
1532 if ( rw_part->isModified() )
1537 if ( isDirty( url ) )
1539 if ( state == Modified )
1541 state = DirtyAndModified;
1552void PartController::doEmitState( KURL
const & url )
1554 emit documentChangedState( url, documentState( url ) );
1557KURL::List PartController::openURLs( )
1560 TQPtrListIterator<KParts::Part> it(*parts());
1561 for ( ; it.current(); ++it)
1563 if ( KParts::ReadOnlyPart *ro_part =
dynamic_cast<KParts::ReadOnlyPart*
>(it.current()) )
1565 list << ro_part->url();
1575PartController::HistoryEntry::HistoryEntry(
const KURL & u,
int l,
int c)
1576 : url(u), line(l), col(c)
1578 id = abs( TQTime::currentTime().msecsTo( TQTime() ) );
1581void PartController::slotBack()
1583 HistoryEntry thatEntry = m_backHistory.front();
1584 m_backHistory.pop_front();
1585 m_backAction->setEnabled( !m_backHistory.isEmpty() );
1587 HistoryEntry thisEntry = createHistoryEntry();
1588 if ( !thisEntry.url.isEmpty() )
1590 m_forwardHistory.push_front( thisEntry );
1591 m_forwardAction->setEnabled(
true );
1594 jumpTo( thatEntry );
1597void PartController::slotForward()
1599 HistoryEntry thatEntry = m_forwardHistory.front();
1600 m_forwardHistory.pop_front();
1601 m_forwardAction->setEnabled( !m_forwardHistory.isEmpty() );
1603 HistoryEntry thisEntry = createHistoryEntry();
1604 if ( !thisEntry.url.isEmpty() )
1606 m_backHistory.push_front( thisEntry );
1607 m_backAction->setEnabled(
true );
1610 jumpTo( thatEntry );
1613void PartController::slotBackAboutToShow()
1615 TDEPopupMenu *popup = m_backAction->popupMenu();
1618 if ( m_backHistory.isEmpty())
return;
1621 TQValueList<HistoryEntry>::ConstIterator it = m_backHistory.begin();
1622 while( i < 10 && it != m_backHistory.end() )
1624 popup->insertItem( (*it).url.fileName() + TQString(
" (%1)").arg( (*it).line +1), (*it).id );
1630void PartController::slotForwardAboutToShow( )
1632 TDEPopupMenu * popup = m_forwardAction->popupMenu();
1635 if ( m_forwardHistory.isEmpty() )
return;
1638 TQValueList<HistoryEntry>::ConstIterator it = m_forwardHistory.begin();
1639 while( i < 10 && it != m_forwardHistory.end() )
1641 popup->insertItem( (*it).url.fileName() + TQString(
" (%1)").arg( (*it).line +1), (*it).id );
1647void PartController::slotBackPopupActivated(
int id )
1649 TQValueList<HistoryEntry>::Iterator it = m_backHistory.begin();
1650 while( it != m_backHistory.end() )
1652 if ( (*it).id ==
id )
1654 HistoryEntry entry = *it;
1655 m_backHistory.erase( m_backHistory.begin(), ++it );
1656 m_backAction->setEnabled( !m_backHistory.isEmpty() );
1658 HistoryEntry thisEntry = createHistoryEntry();
1659 if ( !thisEntry.url.isEmpty() )
1661 m_forwardHistory.push_front( thisEntry );
1662 m_forwardAction->setEnabled(
true );
1672void PartController::slotForwardPopupActivated(
int id )
1674 TQValueList<HistoryEntry>::Iterator it = m_forwardHistory.begin();
1675 while( it != m_forwardHistory.end() )
1677 if ( (*it).id ==
id )
1679 HistoryEntry entry = *it;
1680 m_forwardHistory.erase( m_forwardHistory.begin(), ++it );
1681 m_forwardAction->setEnabled( !m_forwardHistory.isEmpty() );
1683 HistoryEntry thisEntry = createHistoryEntry();
1684 if ( !thisEntry.url.isEmpty() )
1686 m_backHistory.push_front( thisEntry );
1687 m_backAction->setEnabled(
true );
1697void PartController::jumpTo(
const HistoryEntry & entry )
1700 editDocument( entry.url, entry.line, entry.col );
1701 m_isJumping =
false;
1705PartController::HistoryEntry PartController::createHistoryEntry( KParts::ReadOnlyPart * ro_part ) {
1707 ro_part =
dynamic_cast<KParts::ReadOnlyPart*
>( activePart() );
1709 if ( !ro_part )
return HistoryEntry();
1710 KTextEditor::ViewCursorInterface * cursorIface =
dynamic_cast<KTextEditor::ViewCursorInterface*
>( ro_part->widget() );
1711 if ( !cursorIface )
return HistoryEntry();
1715 cursorIface->cursorPositionReal( &line, &col );
1717 return HistoryEntry( ro_part->url(), line, col );
1722void PartController::addHistoryEntry( KParts::ReadOnlyPart * part )
1724 if ( m_isJumping )
return;
1726 HistoryEntry thisEntry = createHistoryEntry( part );
1727 if ( !thisEntry.url.isEmpty() )
1729 HistoryEntry lastEntry = m_backHistory.front();
1730 if ( (lastEntry.url.path() != thisEntry.url.path()) || (lastEntry.line != thisEntry.line) )
1732 m_backHistory.push_front( thisEntry );
1733 m_backAction->setEnabled(
true );
1735 m_forwardHistory.clear();
1736 m_forwardAction->setEnabled(
false );
1740 kdDebug(9000) <<
"** avoiding to create duplicate history entry **" << endl;
1747void PartController::slotWaitForFactoryHack( )
1751 if ( !activePart() )
return;
1753 if (
dynamic_cast<KTextEditor::View*
>( activePart()->widget() ) )
1755 if ( !activePart()->factory() )
1757 TQTimer::singleShot( 100,
this, TQ_SLOT(slotWaitForFactoryHack()) );
1762 EditorProxy::getInstance()->installPopup( activePart() );
1766 if ( MultiBuffer *multiBuffer =
1767 dynamic_cast<MultiBuffer*
>(
1768 EditorProxy::getInstance()->topWidgetForPart( activePart() ) )
1771 KURL url =
dynamic_cast<KParts::ReadOnlyPart*
>( activePart() )->url();
1772 multiBuffer->activePartChanged( url );
1775 emit documentChangedState( url, documentState( url ) );
1779KParts::ReadOnlyPart *PartController::qtDesignerPart()
1781 TQPtrListIterator<KParts::Part> it(*parts());
1782 for ( ; it.current(); ++it)
1784 KInterfaceDesigner::Designer *des =
dynamic_cast<KInterfaceDesigner::Designer*
>(it.current());
1785 if (des && des->designerType() == KInterfaceDesigner::TQtDesigner)
1791KTextEditor::Editor *PartController::openTextDocument(
bool activate )
1793 KTextEditor::Editor *editorpart =
1794 createEditorPart( activate,
false, KURL( i18n(
"unnamed") ) );
1798 if ( !m_presetEncoding.isNull() )
1800 KParts::BrowserExtension * extension =
1801 KParts::BrowserExtension::childObject( editorpart );
1804 KParts::URLArgs args;
1805 args.serviceType = TQString(
"text/plain;" ) + m_presetEncoding;
1806 extension->setURLArgs(args);
1808 m_presetEncoding = TQString();
1812 EditorProxy::getInstance()->topWidgetForPart( editorpart );
1815 integratePart(editorpart, KURL(i18n(
"unnamed")), widget,
true,
true);
1817 EditorProxy::getInstance()->setLineNumber(editorpart, 0, 0);
1823void PartController::textChanged()
1825 if ( KTextEditor::Document * doc =
dynamic_cast<KTextEditor::Document*
>( activePart() ) )
1827 if ( KTextEditor::ViewCursorInterface * vci =
dynamic_cast<KTextEditor::ViewCursorInterface*
>( doc->widget() ) )
1829 m_gotoLastEditPosAction->setEnabled(
true );
1831 m_lastEditPos.url = doc->url();
1832 vci->cursorPosition( &m_lastEditPos.pos.first, &m_lastEditPos.pos.second );
1837void PartController::gotoLastEditPos()
1839 editDocument( m_lastEditPos.url, m_lastEditPos.pos.first, m_lastEditPos.pos.second );
1842void PartController::slotDocumentUrlChanged()
1844 TQObject *obj =
const_cast<TQObject*
>(sender());
1845 KTextEditor::Document *doc =
dynamic_cast<KTextEditor::Document*
>( obj );
1849 MultiBuffer *multiBuffer =
dynamic_cast<MultiBuffer*
>(
1850 EditorProxy::getInstance()->findPartWidget( doc ));
1854 multiBuffer->updateUrlForPart(doc, doc->url());
1856 emit partURLChanged(doc);
1859#include "partcontroller.moc"
static void setupShourtcutTips(KXMLGUIClient *client=0)
Setup shourtcut tips.
Part controler implementation.
void showPart(KParts::Part *part, const TQString &name, const TQString &shortDescription)
static KDevMainWindow * getInstance()
Get a pointer to the single KDevTopLevel object.