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 <kiconloader.h>
40#include <kuserprofile.h>
41#include <kencodingfiledialog.h>
42#include <ksqueezedtextlabel.h>
44#include <tdetexteditor/view.h>
45#include <tdetexteditor/document.h>
46#include <tdetexteditor/viewcursorinterface.h>
47#include <tdetexteditor/encodinginterface.h>
52#include "editorproxy.h"
53#include "documentationpart.h"
54#include "ksavealldialog.h"
56#include "kdevproject.h"
58#include "mimewarningdialog.h"
60#include "kdevjobtimer.h"
63#include "kdevlanguagesupport.h"
65#include "multibuffer.h"
66#include "partcontroller.h"
73using namespace MainWindowUtils;
80 HistoryEntry(
const KURL& u,
const TQString& c ): url( u ), context( c ) {}
83struct ModificationData
85 KTextEditor::Document * doc;
91PartController::PartController(TQWidget *parent)
92 : KDevPartController(parent), _editorFactory(0L), m_currentActivePart(0), m_removingActivePart(false)
94 connect(
this, TQ_SIGNAL(partRemoved(KParts::Part*)),
this, TQ_SLOT(slotPartRemoved(KParts::Part* )) );
95 connect(
this, TQ_SIGNAL(partAdded(KParts::Part*)),
this, TQ_SLOT(slotPartAdded(KParts::Part* )) );
96 connect(
this, TQ_SIGNAL(activePartChanged(KParts::Part*)),
this, TQ_SLOT(slotActivePartChanged(KParts::Part*)));
102 m_openNextAsText =
false;
106PartController::~PartController()
111void PartController::createInstance(TQWidget *parent)
114 s_instance =
new PartController(parent);
124void PartController::setupActions()
128 TDEAction* newAction = KStdAction::open(
this, TQ_SLOT(slotOpenFile()), ac,
"file_open");
129 newAction->setToolTip( i18n(
"Open file") );
130 newAction->setWhatsThis( i18n(
"<b>Open file</b><p>Opens an existing file without adding it to the project.</p>") );
132 m_openRecentAction = KStdAction::openRecent(
this, TQ_SLOT(slotOpenRecent(
const KURL&) ), ac,
"file_open_recent" );
133 m_openRecentAction->setWhatsThis(TQString(
"<b>%1</b><p>%2").arg(beautifyToolTip(m_openRecentAction->text())).arg(i18n(
"Opens recently opened file.")));
134 m_openRecentAction->loadEntries( kapp->config(),
"RecentFiles" );
136 m_saveAllFilesAction =
new TDEAction(i18n(
"Save Al&l"), 0,
this, TQ_SLOT(slotSaveAllFiles()), ac,
"file_save_all");
137 m_saveAllFilesAction->setToolTip( i18n(
"Save all modified files") );
138 m_saveAllFilesAction->setWhatsThis(i18n(
"<b>Save all</b><p>Saves all modified files."));
139 m_saveAllFilesAction->setEnabled(
false);
141 m_revertAllFilesAction =
new TDEAction(i18n(
"Rever&t All"), 0,
this, TQ_SLOT(slotRevertAllFiles()), ac,
"file_revert_all");
142 m_revertAllFilesAction->setToolTip(i18n(
"Revert all changes"));
143 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."));
144 m_revertAllFilesAction->setEnabled(
false);
146 m_closeWindowAction = KStdAction::close(
this, TQ_SLOT(slotCloseWindow()), ac,
"file_close");
147 m_closeWindowAction->setToolTip( i18n(
"Close current file") );
148 m_closeWindowAction->setWhatsThis(TQString(
"<b>%1</b><p>%2").arg(beautifyToolTip(m_closeWindowAction->text())).arg(i18n(
"Closes current file.")));
149 m_closeWindowAction->setEnabled(
false);
151 m_closeAllWindowsAction =
new TDEAction(i18n(
"Close All"), 0,
this, TQ_SLOT(slotCloseAllWindows()), ac,
"file_close_all");
152 m_closeAllWindowsAction->setToolTip( i18n(
"Close all files") );
153 m_closeAllWindowsAction->setWhatsThis(i18n(
"<b>Close all</b><p>Close all opened files."));
154 m_closeAllWindowsAction->setEnabled(
false);
156 m_closeOtherWindowsAction =
new TDEAction(i18n(
"Close All Others"), 0,
this, TQ_SLOT(slotCloseOtherWindows()), ac,
"file_closeother");
157 m_closeOtherWindowsAction->setToolTip( i18n(
"Close other files") );
158 m_closeOtherWindowsAction->setWhatsThis(i18n(
"<b>Close all others</b><p>Close all opened files except current."));
159 m_closeOtherWindowsAction->setEnabled(
false);
161 new TDEActionSeparator(ac,
"dummy_separator");
163 m_backAction =
new TDEToolBarPopupAction(i18n(
"Back"),
"back", 0,
this, TQ_SLOT(slotBack()), ac,
"history_back");
164 m_backAction->setEnabled(
false );
165 m_backAction->setToolTip(i18n(
"Back"));
166 m_backAction->setWhatsThis(i18n(
"<b>Back</b><p>Moves backwards one step in the navigation history."));
167 connect(m_backAction->popupMenu(), TQ_SIGNAL(aboutToShow()),
this, TQ_SLOT(slotBackAboutToShow()));
168 connect(m_backAction->popupMenu(), TQ_SIGNAL(activated(
int)),
this, TQ_SLOT(slotBackPopupActivated(
int)));
170 m_forwardAction =
new TDEToolBarPopupAction(i18n(
"Forward"),
"forward", 0,
this, TQ_SLOT(slotForward()), ac,
"history_forward");
171 m_forwardAction->setEnabled(
false );
172 m_forwardAction->setToolTip(i18n(
"Forward"));
173 m_forwardAction->setWhatsThis(i18n(
"<b>Forward</b><p>Moves forward one step in the navigation history."));
174 connect(m_forwardAction->popupMenu(), TQ_SIGNAL(aboutToShow()),
this, TQ_SLOT(slotForwardAboutToShow()));
175 connect(m_forwardAction->popupMenu(), TQ_SIGNAL(activated(
int)),
this, TQ_SLOT(slotForwardPopupActivated(
int)));
177 m_gotoLastEditPosAction =
new TDEAction( i18n(
"Goto Last Edit Position"),
"go-bottom", 0,
this, TQ_SLOT(gotoLastEditPos()), ac,
"goto_last_edit_pos" );
178 m_gotoLastEditPosAction->setEnabled(
false );
179 m_gotoLastEditPosAction->setToolTip( i18n(
"Goto Last Edit Position") );
180 m_gotoLastEditPosAction->setWhatsThis( i18n(
"<b>Goto Last Edit Position</b><p>Open the last edited file and position cursor at the point of edit") );
183void PartController::setEncoding(
const TQString &encoding)
185 m_presetEncoding = encoding;
188KParts::Part* PartController::findOpenDocument(
const KURL& url)
191 KParts::Part * part = partForURL( url );
198 if ( API::getInstance()->project() )
200 KURL partURL = findURLInProject( url );
202 return partForURL( partURL );
208KURL PartController::findURLInProject(
const KURL& url)
210 TQStringList fileList = API::getInstance()->project()->allFiles();
212 bool filenameOnly = (url.url().find(
'/') == -1);
213 TQString filename = filenameOnly ?
"/" :
"";
214 filename += url.url();
216 for (TQStringList::Iterator it = fileList.begin(); it != fileList.end(); ++it) {
217 if ((*it).endsWith(filename)) {
219 return KURL( API::getInstance()->project()->projectDirectory() +
"/" + *it );
226void PartController::editDocument(
const KURL &inputUrl,
int lineNum,
int col)
228 editDocumentInternal(inputUrl, lineNum, col);
231void PartController::splitCurrentDocument(
const KURL &inputUrl,
232 int lineNum,
int col)
234 editDocumentInternal(inputUrl, lineNum, col,
true,
true);
237void PartController::scrollToLineColumn(
const KURL &inputUrl,
238 int lineNum,
int col,
bool storeHistory )
240 if ( KParts::ReadOnlyPart *existingPart = partForURL( inputUrl ) )
242 if( storeHistory ) addHistoryEntry( existingPart );
243 EditorProxy::getInstance()->setLineNumber( existingPart, lineNum, col );
248void PartController::editDocumentInternal(
const KURL & inputUrl,
int lineNum,
249 int col,
bool activate,
250 bool addToCurrentBuffer )
252 kdDebug(9000) << k_funcinfo <<
"\n " << inputUrl.prettyURL()
253 <<
" linenum " << lineNum <<
" activate? " << activate
254 <<
" addToCurrentBuffer? " << addToCurrentBuffer << endl;
260 if ( KParts::Part *existingPart = partForURL( url ) )
263 if ( !m_presetEncoding.isNull() )
265 if ( KTextEditor::EncodingInterface * ei =
dynamic_cast<KTextEditor::EncodingInterface*
>( existingPart ) )
267 ei->setEncoding( m_presetEncoding );
269 m_presetEncoding = TQString();
273 activatePart( existingPart );
274 EditorProxy::getInstance()->setLineNumber( existingPart, lineNum, col );
279 if ( !url.isValid() || !TDEIO::NetAccess::exists(url,
false, 0) )
284 if ( API::getInstance()->project() )
286 if (url.isRelativeURL(url.url())) {
287 KURL relURL(API::getInstance()->project()->projectDirectory());
288 relURL.addPath( url.url() );
290 kdDebug() << k_funcinfo <<
"Looking for file in project dir: " << API::getInstance()->project()->projectDirectory() <<
" url " << url.url() <<
" transformed to " << relURL.url() <<
": " << done << endl;
291 if (relURL.isValid() && TDEIO::NetAccess::exists(relURL,
false, 0)) {
296 KURL relURL(API::getInstance()->project()->buildDirectory());
297 relURL.addPath( url.url() );
298 kdDebug() << k_funcinfo <<
"Looking for file in build dir: " << API::getInstance()->project()->buildDirectory() <<
" url " << url.url() <<
" transformed to " << relURL.url() <<
": " << done << endl;
299 if (relURL.isValid() && TDEIO::NetAccess::exists(relURL,
false, 0)) {
307 url = findURLInProject(url);
309 if ( !url.isValid() || !TDEIO::NetAccess::exists(url,
false, 0) )
311 url = API::getInstance()->project()->projectDirectory() +
"/" + url.path();
318 if ( !done && ( !url.isValid() || !TDEIO::NetAccess::exists(url,
false, 0) ))
321 kdDebug(9000) <<
"cannot find URL: " << url.url() << endl;
330 if (url.isLocalFile())
332 TQString path = url.path();
333 path = URLUtil::canonicalPath(path);
334 if ( !path.isEmpty() )
339 KParts::Part *existingPart = partForURL(url);
343 activatePart(existingPart);
344 EditorProxy::getInstance()->setLineNumber(existingPart, lineNum, col);
348 if ( !addToCurrentBuffer )
350 if ( KDevLanguageSupport *lang =
351 API::getInstance()->languageSupport() )
355 addToCurrentBuffer = lang->shouldSplitDocument( inputUrl );
357 if ( addToCurrentBuffer )
360 "languagePart() insists addToCurrentBuffer = true" << endl;
369 KMimeType::Ptr MimeType = KMimeType::findByURL( url );
371 kdDebug(9000) <<
"mimeType = " << MimeType->name() << endl;
374 if ( MimeType->is(
"inode/directory" ) )
379 if ( !m_presetEncoding.isNull() )
381 m_openNextAsText =
true;
384 TDEConfig *config = kapp->config();
385 config->setGroup(
"General Options");
388 if ( !m_openNextAsText && MimeType->is(
"application/x-designer" ) )
390 TQString DesignerSetting = config->readEntry(
"DesignerSetting",
"ExternalDesigner" );
391 TQString designerExec =
"designer";
392 TQStringList designerPluginPaths;
393 TQDomDocument* dom = API::getInstance()->projectDom();
398 DesignerSetting = DomUtil::readEntry(*dom,
"/kdevcppsupport/qt/designerintegration", DesignerSetting );
399 designerExec = DomUtil::readEntry(*dom,
"/kdevcppsupport/qt/designer", designerExec );
401 if ( DesignerSetting ==
"ExternalKDevDesigner" )
403 designerExec =
"kdevdesigner";
405 else if ( DesignerSetting ==
"EmbeddedKDevDesigner" )
407 if ( KParts::ReadOnlyPart *designerPart = qtDesignerPart() )
410 activatePart(designerPart);
411 designerPart->openURL(url);
414 else if ( KParts::Factory * KDevDesignerFactory =
static_cast<KParts::Factory*
>( KLibLoader::self()->factory( TQFile::encodeName(
"libkdevdesignerpart" ) ) ) )
416 KParts::ReadWritePart * kdevpart =
static_cast<KParts::ReadWritePart*
>( KDevDesignerFactory->createPart(
TopLevel::getInstance()->main(), 0, 0, 0,
"KParts::ReadWritePart" ) );
417 kdevpart->openURL( url );
419 integratePart( kdevpart, url );
420 m_openRecentAction->addURL( url );
421 m_openRecentAction->saveEntries( kapp->config(),
"RecentFiles" );
426 if( designerPluginPaths.isEmpty() )
427 KRun::runCommand( designerExec+
" "+url.pathOrURL() );
429 KRun::runCommand(
"TQT_PLUGIN_PATH=\""+designerPluginPaths.join(
":")+
"\" "+designerExec+
" "+url.pathOrURL() );
434 config->setGroup(
"General");
436 TQStringList texttypeslist = config->readListEntry(
"TextTypes" );
437 if ( texttypeslist.contains( MimeType->name() ) )
439 m_openNextAsText =
true;
443 TQVariant v = MimeType->property(
"X-TDE-text");
447 if ( m_openNextAsText || isText || MimeType->is(
"application/x-zerosize" ) )
449 KTextEditor::Editor *editorpart =
450 createEditorPart( activate, addToCurrentBuffer, url );
453 if ( m_presetEncoding.isNull() && API::getInstance()->projectDom() )
455 TQDomDocument * projectDom = API::getInstance()->projectDom();
456 m_presetEncoding = DomUtil::readEntry( *projectDom,
"/general/defaultencoding", TQString() );
459 if ( !m_presetEncoding.isNull() )
461 if ( KTextEditor::EncodingInterface * ei =
dynamic_cast<KTextEditor::EncodingInterface*
>( editorpart ) )
463 ei->setEncoding( m_presetEncoding );
465 m_presetEncoding = TQString();
470 TQWidget * widget = EditorProxy::getInstance()->topWidgetForPart( editorpart );
472 integratePart(editorpart, url, widget,
true, activate, addToCurrentBuffer);
473 EditorProxy::getInstance()->setLineNumber(editorpart, lineNum, col);
475 m_openNextAsText =
false;
477 m_openRecentAction->addURL( url );
478 m_openRecentAction->saveEntries( kapp->config(),
"RecentFiles" );
486 KParts::Factory *factory = 0;
489 TQString services[] = {
"KParts/ReadWritePart",
"KParts/ReadOnlyPart" };
490 TQString classnames[] = {
"KParts::ReadWritePart",
"KParts::ReadOnlyPart" };
491 for (uint i=0; i<2; ++i)
493 factory = findPartFactory( MimeType->name(), services[i] );
496 className = classnames[i];
501 kdDebug(9000) <<
"factory = " << factory << endl;
506 KParts::ReadOnlyPart *part =
static_cast<KParts::ReadOnlyPart*
>( factory->createPart(
TopLevel::getInstance()->main(), 0, 0, 0, className.latin1() ) );
509 part->openURL( url );
512 if (
dynamic_cast<KTextEditor::Editor*
>( part ) )
514 integratePart(part, url, part->widget(),
true, activate);
515 EditorProxy::getInstance()->setLineNumber(part, lineNum, col);
519 integratePart( part, url );
522 m_openRecentAction->addURL( url );
523 m_openRecentAction->saveEntries( kapp->config(),
"RecentFiles" );
528 MimeWarningDialog dlg;
529 dlg.text2->setText( TQString(
"<qt><b>%1</b></qt>" ).arg(url.path()));
530 dlg.text3->setText( dlg.text3->text().arg(MimeType->name()) );
532 if ( dlg.exec() == TQDialog::Accepted )
534 if ( dlg.open_with_kde->isChecked() )
536 KRun::runURL(url, MimeType->name() );
540 if ( dlg.always_open_as_text->isChecked() )
542 TDEConfig *config = kapp->config();
543 config->setGroup(
"General");
544 TQStringList texttypeslist = config->readListEntry(
"TextTypes" );
545 texttypeslist << MimeType->name();
546 config->writeEntry(
"TextTypes", texttypeslist );
548 m_openNextAsText =
true;
549 editDocument( url, lineNum, col );
556void PartController::showDocument(
const KURL &url,
bool newWin)
558 TQString fixedPath = HTMLDocumentationPart::resolveEnvVarsInURL(url.url());
559 KURL docUrl(fixedPath);
560 kdDebug(9000) <<
"SHOW: " << docUrl.url() << endl;
562 if ( docUrl.isLocalFile() && KMimeType::findByURL(docUrl)->name() !=
"text/html" ) {
565 editDocument( docUrl );
571 HTMLDocumentationPart *part =
dynamic_cast<HTMLDocumentationPart*
>(activePart());
574 part =
new HTMLDocumentationPart;
575 integratePart(part,docUrl);
576 connect(part, TQ_SIGNAL(fileNameChanged(KParts::ReadOnlyPart* )),
577 this, TQ_SIGNAL(partURLChanged(KParts::ReadOnlyPart* )));
583 part->openURL(docUrl);
586KParts::Factory *PartController::findPartFactory(
const TQString &mimeType,
const TQString &partType,
const TQString &preferredName)
588 TDETrader::OfferList offers = TDETrader::self()->query(mimeType, TQString(
"'%1' in ServiceTypes").arg(partType));
590 if (offers.count() > 0)
592 KService::Ptr ptr = 0;
594 if ( !preferredName.isEmpty() ) {
595 TDETrader::OfferList::Iterator it;
596 for (it = offers.begin(); it != offers.end(); ++it) {
597 if ((*it)->desktopEntryName() == preferredName) {
604 ptr = offers.first();
606 return static_cast<KParts::Factory*
>(KLibLoader::self()->factory(TQFile::encodeName(ptr->library())));
612KTextEditor::Editor * PartController::createEditorPart(
bool activate,
613 bool addToCurrentBuffer,
616 MultiBuffer *multiBuffer = 0;
617 if ( addToCurrentBuffer )
620 dynamic_cast<MultiBuffer*
>(
621 EditorProxy::getInstance()->topWidgetForPart( activePart() )
626 kdDebug(9000) <<
"Creating a new MultiBuffer for "
627 << url.fileName() << endl;
631 static bool alwaysActivate =
true;
633 kapp->config()->setGroup(
"Editor");
634 TQString preferred = kapp->config()->readPathEntry(
"EmbeddedKTextEditor");
638 if ( preferred !=
"kyzispart" )
639 alwaysActivate =
false;
641 KTextEditor::Editor *editorpart =
642 dynamic_cast<KTextEditor::Editor*
>(multiBuffer->createPart(
"text/plain",
643 "KTextEditor/Document",
644 alwaysActivate | activate ?
645 "KTextEditor::Editor" :
"KTextEditor::Document",
650 editorpart->openURL( url );
652 multiBuffer->registerURL( url, editorpart );
653 multiBuffer->setDelayedActivation( !activate );
657void PartController::integratePart(KParts::Part *part,
const KURL &url,
658 TQWidget* widget,
bool isTextEditor,
659 bool activate,
bool addToCurrentBuffer )
661 if (!widget) widget = part->widget();
665 kdDebug(9000) <<
"no widget for this part!!" << endl;
669 if ( !addToCurrentBuffer )
672 addPart(part, activate);
675 KParts::ReadOnlyPart *ro_part =
dynamic_cast<KParts::ReadOnlyPart*
>(part);
676 if ( !ro_part )
return;
678 emit loadedFile( ro_part->url() );
680 connect( part, TQ_SIGNAL(modifiedOnDisc(Kate::Document*,
bool,
unsigned char)),
this, TQ_SLOT(slotDocumentDirty(Kate::Document*,
bool,
unsigned char)) );
683 connect(part, TQ_SIGNAL(completed()),
this, TQ_SLOT(slotUploadFinished()));
693 integrateTextEditorPart(
static_cast<KTextEditor::Document*
>(part));
695 KInterfaceDesigner::Designer *designerPart =
dynamic_cast<KInterfaceDesigner::Designer *
>(part);
696 if (designerPart && API::getInstance()->languageSupport())
698 kdDebug() <<
"integrating designer part with language support" << endl;
699 connect(designerPart, TQ_SIGNAL(addedFunction(DesignerType,
const TQString&, Function )),
700 API::getInstance()->languageSupport(),
701 TQ_SLOT(addFunction(DesignerType,
const TQString&, Function )));
702 connect(designerPart, TQ_SIGNAL(editedFunction(DesignerType,
const TQString&, Function, Function )), API::getInstance()->languageSupport(),
703 TQ_SLOT(editFunction(DesignerType,
const TQString&, Function, Function )));
704 connect(designerPart, TQ_SIGNAL(removedFunction(DesignerType,
const TQString&, Function )),
705 API::getInstance()->languageSupport(),
706 TQ_SLOT(removeFunction(DesignerType,
const TQString&, Function )));
707 connect(designerPart, TQ_SIGNAL(editFunction(DesignerType,
const TQString&,
const TQString& )),
708 API::getInstance()->languageSupport(),
709 TQ_SLOT(openFunction(DesignerType,
const TQString&,
const TQString& )));
710 connect(designerPart, TQ_SIGNAL(editSource(DesignerType,
const TQString& )),
711 API::getInstance()->languageSupport(),
712 TQ_SLOT(openSource(DesignerType,
const TQString& )));
713 connect(designerPart, TQ_SIGNAL(newStatus(
const TQString &,
int)),
714 this, TQ_SLOT(slotNewDesignerStatus(
const TQString &,
int)));
718void PartController::integrateTextEditorPart(KTextEditor::Document* doc)
735 connect( doc, TQ_SIGNAL(textChanged()),
this, TQ_SLOT(textChanged()) );
736 connect( doc, TQ_SIGNAL(fileNameChanged()),
737 this, TQ_SLOT(slotDocumentUrlChanged()));
741 connect( doc->widget(), TQ_SIGNAL(dropEventPass(TQDropEvent *)),
745 if ( KTextEditor::View * view =
dynamic_cast<KTextEditor::View*
>( doc->widget() ) )
747 TDEActionCollection* c = view->actionCollection();
751 if (TDEAction* a = c->action(
"view_folding_markers"))
753 if (a->shortcut() == TDEShortcut(Key_F9))
754 a->setShortcut(TDEShortcut());
757 if (TDEAction* a = c->action(
"view_dynamic_word_wrap"))
759 if (a->shortcut() == TDEShortcut(Key_F10))
760 a->setShortcut(TDEShortcut());
763 if (TDEAction* a = c->action(
"view_line_numbers"))
765 if (a->shortcut() == TDEShortcut(Key_F11))
766 a->setShortcut(TDEShortcut());
778 TQPtrList<KTextEditor::View> list = doc->views();
779 TQPtrListIterator<KTextEditor::View> it( list );
780 while ( it.current() )
782 connect( it, TQ_SIGNAL( newStatus() ),
this, TQ_SLOT( slotNewStatus() ) );
787void PartController::slotPartAdded( KParts::Part * part )
789 kdDebug(9000) << k_funcinfo << endl;
791 if ( KParts::ReadOnlyPart * ro_part =
dynamic_cast<KParts::ReadOnlyPart*
>( part ) )
793 updatePartURL( ro_part );
799void PartController::slotPartRemoved( KParts::Part * part )
801 kdDebug(9000) << k_funcinfo << endl;
803 _partURLMap.remove(
static_cast<KParts::ReadOnlyPart*
>(part) );
805 if ( part == m_currentActivePart )
807 m_removingActivePart =
true;
813void PartController::updatePartURL( KParts::ReadOnlyPart * ro_part )
815 if ( ro_part->url().isEmpty() )
817 kdDebug(9000) <<
"updatePartURL() called with empty URL for part: " << ro_part << endl;
820 _partURLMap[ ro_part ] = ro_part->url();
823bool PartController::partURLHasChanged( KParts::ReadOnlyPart * ro_part )
825 if ( _partURLMap.contains( ro_part ) && !ro_part->url().isEmpty() )
827 if ( _partURLMap[ ro_part ] != ro_part->url() )
835KURL PartController::storedURLForPart( KParts::ReadOnlyPart * ro_part )
837 if ( _partURLMap.contains( ro_part ) )
839 return _partURLMap[ ro_part ];
845void PartController::slotUploadFinished()
847 KParts::ReadOnlyPart *ro_part =
const_cast<KParts::ReadOnlyPart*
>(
dynamic_cast<const KParts::ReadOnlyPart*
>(sender()) );
848 if ( !ro_part )
return;
850 if ( partURLHasChanged( ro_part ) )
852 emit partURLChanged( ro_part );
853 updatePartURL( ro_part );
857KParts::ReadOnlyPart *PartController::partForURL(
const KURL &url)
859 TQPtrListIterator<KParts::Part> it(*parts());
860 for ( ; it.current(); ++it)
862 KParts::ReadOnlyPart *ro_part =
dynamic_cast<KParts::ReadOnlyPart*
>(it.current());
863 if (ro_part && url.path() == ro_part->url().path())
869KParts::Part * PartController::partForWidget(
const TQWidget * widget )
871 TQPtrListIterator<KParts::Part> it(*parts());
872 for ( ; it.current(); ++it)
874 if ( it.current()->widget() == widget )
883void PartController::activatePart(KParts::Part *part)
887 TQWidget * widget = EditorProxy::getInstance()->widgetForPart( part );
897 TQWidget* w2 = EditorProxy::getInstance()->widgetForPart( part );
902bool PartController::closePart(KParts::Part *part)
904 KParts::ReadOnlyPart * ro_part =
905 dynamic_cast<KParts::ReadOnlyPart*
>( part );
907 if ( !ro_part )
return true;
909 KURL url = ro_part->url();
911 if (TQWidget* w = EditorProxy::getInstance()->topWidgetForPart( part ) )
913 if ( MultiBuffer *multiBuffer =
dynamic_cast<MultiBuffer*
>( w ) )
915 kdDebug(9000) <<
"About to delete MultiBuffered document..."
916 <<
" numberOfBuffers: " << multiBuffer->numberOfBuffers()
917 <<
" isActivated: " << multiBuffer->isActivated()
919 if ( !multiBuffer->closeURL( url ) )
922 if ( multiBuffer->numberOfBuffers() == 0
923 || !multiBuffer->isActivated() )
926 _dirtyDocuments.remove(
static_cast<KParts::ReadWritePart*
>( ro_part ) );
927 emit closedFile( url );
932 multiBuffer->deleteLater();
938 _dirtyDocuments.remove(
static_cast<KParts::ReadWritePart*
>( ro_part ) );
940 emit closedFile( url );
943 setActivePart( multiBuffer->activeBuffer() );
947 else if ( !ro_part->closeURL() )
951 else if ( !ro_part->closeURL() )
955 _dirtyDocuments.remove(
static_cast<KParts::ReadWritePart*
>( ro_part ) );
956 emit closedFile( url );
964void PartController::updateMenuItems()
966 bool hasWriteParts =
false;
967 bool hasReadOnlyParts =
false;
969 TQPtrListIterator<KParts::Part> it(*parts());
970 for ( ; it.current(); ++it)
972 if (it.current()->inherits(
"KParts::ReadWritePart"))
973 hasWriteParts =
true;
974 if (it.current()->inherits(
"KParts::ReadOnlyPart"))
975 hasReadOnlyParts =
true;
978 m_saveAllFilesAction->setEnabled(hasWriteParts);
979 m_revertAllFilesAction->setEnabled(hasWriteParts);
980 m_closeWindowAction->setEnabled(hasReadOnlyParts);
981 m_closeAllWindowsAction->setEnabled(hasReadOnlyParts);
982 m_closeOtherWindowsAction->setEnabled(hasReadOnlyParts);
984 m_backAction->setEnabled( !m_backHistory.isEmpty() );
987void PartController::slotRevertAllFiles()
992void PartController::reloadFile(
const KURL & url )
994 KParts::ReadWritePart * part =
dynamic_cast<KParts::ReadWritePart*
>( partForURL( url ) );
997 if ( part->isModified() )
1000 i18n(
"The file \"%1\" is modified in memory. Are you sure you want to reload it? (Local changes will be lost.)" ).arg( url.path() ),
1001 i18n(
"File is Modified" ), i18n(
"Reload"), i18n(
"Do Not Reload") ) == KMessageBox::Yes )
1003 part->setModified(
false );
1011 unsigned int line = 0;
unsigned int col = 0;
1012 KTextEditor::ViewCursorInterface * iface =
dynamic_cast<KTextEditor::ViewCursorInterface*
>( part->widget() );
1015 iface->cursorPositionReal( &line, &col );
1018 part->openURL( url );
1020 _dirtyDocuments.remove( part );
1021 emit documentChangedState( url, Clean );
1025 iface->setCursorPositionReal( line, col );
1030void PartController::revertFiles(
const KURL::List & list )
1032 KURL::List::ConstIterator it = list.begin();
1033 while ( it != list.end() )
1040void PartController::revertAllFiles()
1042 revertFiles( openURLs() );
1045void PartController::slotCloseWindow()
1047 closePart( activePart() );
1050KURL::List PartController::modifiedDocuments()
1052 KURL::List modFiles;
1054 TQPtrListIterator<KParts::Part> it( *parts() );
1055 while( it.current() )
1057 KParts::ReadWritePart *rw_part =
dynamic_cast<KParts::ReadWritePart*
>(it.current());
1058 if ( rw_part && rw_part->isModified() )
1060 modFiles << rw_part->url();
1067void PartController::slotSave()
1069 kdDebug(9000) << k_funcinfo << endl;
1071 if ( KParts::ReadWritePart * part =
dynamic_cast<KParts::ReadWritePart*
>( activePart() ) )
1073 saveFile( part->url() );
1077void PartController::slotReload()
1079 kdDebug(9000) << k_funcinfo << endl;
1081 if ( KParts::ReadWritePart * part =
dynamic_cast<KParts::ReadWritePart*
>( activePart() ) )
1083 reloadFile( part->url() );
1087void PartController::slotSaveAllFiles()
1092bool PartController::saveFile(
const KURL & url,
bool force )
1094 KParts::ReadWritePart * part =
dynamic_cast<KParts::ReadWritePart*
>( partForURL( url ) );
1095 if ( !part )
return true;
1097 switch( documentState( url ) )
1104 kdDebug(9000) <<
"Forced save" << endl;
1108 kdDebug(9000) <<
"Normal save" << endl;
1112 case DirtyAndModified:
1115 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() ),
1116 i18n(
"File Externally Modified"), i18n(
"Overwrite"), i18n(
"Do Not Overwrite") );
1117 if ( code == KMessageBox::Yes )
1119 kdDebug(9000) <<
"Dirty save!!" << endl;
1121 else if ( code == KMessageBox::No )
1138 _dirtyDocuments.remove( part );
1139 emit documentChangedState( url, Clean );
1140 emit savedFile( url );
1146bool PartController::saveAllFiles()
1148 return saveFiles( openURLs() );
1151bool PartController::saveFiles( KURL::List
const & filelist )
1153 KURL::List::ConstIterator it = filelist.begin();
1154 while ( it != filelist.end() )
1156 if (saveFile( *it )==
false)
1163bool PartController::querySaveFiles()
1165 return saveFilesDialog( KURL::List() );
1168void PartController::clearModified( KURL::List
const & filelist )
1170 KURL::List::ConstIterator it = filelist.begin();
1171 while ( it != filelist.end() )
1173 KParts::ReadWritePart * rw_part =
dynamic_cast<KParts::ReadWritePart*
>( partForURL( *it ) );
1176 rw_part->setModified(
false );
1182bool PartController::saveFilesDialog( KURL::List
const & ignoreList )
1184 KURL::List modList = modifiedDocuments();
1186 if ( modList.count() > 0 && modList != ignoreList )
1189 if ( dlg.exec() == TQDialog::Accepted )
1191 saveFiles( dlg.filesToSave() );
1192 clearModified( dlg.filesNotToSave() );
1202bool PartController::closeFilesDialog( KURL::List
const & ignoreList )
1204 if ( !saveFilesDialog( ignoreList ) )
return false;
1206 TQPtrList<KParts::Part> partList( *parts() );
1207 TQPtrListIterator<KParts::Part> it( partList );
1208 while ( KParts::Part* part = it.current() )
1210 KParts::ReadOnlyPart * ro_part =
dynamic_cast<KParts::ReadOnlyPart*
>( part );
1211 if ( ro_part && !ignoreList.contains( ro_part->url() ) || !ro_part )
1220bool PartController::closeFiles(
const KURL::List & list )
1222 KURL::List::ConstIterator it = list.begin();
1223 while ( it != list.end() )
1225 if ( !closePart( partForURL( *it ) ) )
1234bool PartController::closeFile(
const KURL & url )
1236 return closePart( partForURL( url ) );
1239bool PartController::closeAllFiles()
1241 return closeFilesDialog( KURL::List() );
1244void PartController::slotCloseAllWindows()
1249bool PartController::closeAllOthers(
const KURL & url )
1251 KURL::List ignoreList;
1252 ignoreList.append( url );
1254 return closeFilesDialog( ignoreList );
1258void PartController::slotCloseOtherWindows()
1260 if ( KParts::ReadOnlyPart * active =
dynamic_cast<KParts::ReadOnlyPart*
>( activePart() ) )
1262 closeAllOthers( active->url() );
1266void PartController::slotOpenFile()
1268 TQString DefaultEncoding;
1269 if ( TQDomDocument * projectDom = API::getInstance()->projectDom() )
1271 DefaultEncoding = DomUtil::readEntry( *projectDom,
"/general/defaultencoding", TQString() );
1274 if ( DefaultEncoding.isEmpty() )
1277 TDEConfig * config = kapp->config();
1278 config->setGroup(
"Kate Document Defaults");
1279 DefaultEncoding = config->readEntry(
"Encoding", TQString() );
1282 KEncodingFileDialog::Result result = KEncodingFileDialog::getOpenURLsAndEncoding( DefaultEncoding, TQString(),
1285 for ( KURL::List::Iterator it = result.URLs.begin(); it != result.URLs.end(); ++it )
1287 m_presetEncoding = result.encoding;
1288 editDocument( *it );
1292void PartController::slotOpenRecent(
const KURL& url )
1294 editDocument( url );
1296 m_openRecentAction->setCurrentItem( -1 );
1299bool PartController::readyToClose()
1301 blockSignals(
true );
1308void PartController::slotActivePartChanged( KParts::Part *part )
1310 kdDebug(9000) << k_funcinfo << part << endl;
1312 if ( !m_isJumping && !m_removingActivePart )
1314 if ( KParts::ReadOnlyPart * ro_part =
dynamic_cast<KParts::ReadOnlyPart*
>(m_currentActivePart) )
1316 addHistoryEntry( ro_part );
1320 m_currentActivePart = part;
1321 m_removingActivePart =
false;
1324 KXMLGUIClient* client =
dynamic_cast<KXMLGUIClient*
>(part->widget());
1329 TQTimer::singleShot( 100,
this, TQ_SLOT(slotWaitForFactoryHack()) );
1334 if (!part->widget()) {
1339 TQPtrListIterator<KParts::Part> it(*parts());
1340 for ( ; it.current(); ++it)
1342 if( it.current() == part ){
1344 activatePart( it.current() );
1354void PartController::slotDocumentDirty( Kate::Document * d,
bool isModified,
unsigned char reason )
1356 kdDebug(9000) << k_funcinfo << endl;
1359 KTextEditor::Document * doc = 0;
1361 TQPtrListIterator<KParts::Part> it( *parts() );
1362 while( it.current() )
1364 if ( (
void*)it.current() == (
void*)d )
1366 doc =
dynamic_cast<KTextEditor::Document*
>( it.current() );
1377 ModificationData * p =
new ModificationData;
1379 p->isModified = isModified;
1381 KDevJobTimer::singleShot( 0,
this, TQ_SLOT(slotDocumentDirtyStepTwo(
void*)), p );
1385void PartController::slotDocumentDirtyStepTwo(
void * payload )
1387 if ( !payload )
return;
1389 ModificationData * p =
reinterpret_cast<ModificationData*
>( payload );
1390 KTextEditor::Document * doc = p->doc;
1393 bool haveDocument =
false;
1394 if(
const TQPtrList<KParts::Part> * partlist = parts() )
1396 TQPtrListIterator<KParts::Part> it( *partlist );
1397 while ( KParts::Part * part = it.current() )
1399 if ( p->doc ==
dynamic_cast<KTextEditor::Document*
>( part ) )
1401 haveDocument =
true;
1407 if ( !haveDocument )
return;
1409 bool isModified = p->isModified;
1410 unsigned char reason = p->reason;
1413 KURL url = storedURLForPart( doc );
1414 if ( url.isEmpty() )
1416 kdDebug(9000) <<
"Warning!! the stored url is empty. Bailing out!" << endl;
1421 if ( !_dirtyDocuments.contains( doc ) )
1423 _dirtyDocuments.append( doc );
1426 if ( reactToDirty( url, reason ) )
1429 emit documentChangedState( url, Clean );
1430 _dirtyDocuments.remove( doc );
1439 _dirtyDocuments.remove( doc );
1440 emit documentChangedState( url, Clean );
1443 kdDebug(9000) << doc->url().url() << endl;
1444 kdDebug(9000) << isModified << endl;
1445 kdDebug(9000) << reason << endl;
1448bool PartController::isDirty( KURL
const & url )
1450 return _dirtyDocuments.contains(
static_cast<KTextEditor::Document*
>( partForURL( url ) ) );
1453bool PartController::reactToDirty( KURL
const & url,
unsigned char reason )
1455 TDEConfig *config = kapp->config();
1456 config->setGroup(
"Editor");
1457 TQString dirtyAction = config->readEntry(
"DirtyAction" );
1459 if ( dirtyAction ==
"nothing" )
return false;
1461 bool isModified =
true;
1462 if( KParts::ReadWritePart * part =
dynamic_cast<KParts::ReadWritePart*
>( partForURL( url ) ) )
1464 isModified = part->isModified();
1468 kdDebug(9000) << k_funcinfo <<
" Warning. Not a ReadWritePart." << endl;
1475 i18n(
"Conflict: The file \"%1\" has changed on disk while being modified in memory.\n\n"
1476 "You should investigate before saving to make sure you are not losing data.").arg( url.path() ),
1484 i18n(
"Warning: The file \"%1\" has been deleted on disk.\n\n"
1485 "If this was not your intention, make sure to save this file now.").arg( url.path() ),
1486 i18n(
"File Deleted") );
1490 if ( dirtyAction ==
"alert" )
1493 i18n(
"The file \"%1\" has changed on disk.\n\nDo you want to reload it?").arg( url.path() ),
1494 i18n(
"File Changed"), i18n(
"Reload"), i18n(
"Do Not Reload") ) == KMessageBox::No )
1506void PartController::slotNewDesignerStatus(
const TQString &formName,
int status)
1508 kdDebug(9000) << k_funcinfo << endl;
1509 kdDebug(9000) <<
" formName: " << formName <<
", status: " << status << endl;
1510 emit documentChangedState( KURL::fromPathOrURL(formName), DocumentState(status) );
1513void PartController::slotNewStatus( )
1515 kdDebug(9000) << k_funcinfo << endl;
1517 TQObject * senderobj =
const_cast<TQObject*
>(sender());
1518 KTextEditor::View * view =
dynamic_cast<KTextEditor::View*
>( senderobj );
1521 doEmitState( view->document()->url() );
1525DocumentState PartController::documentState( KURL
const & url )
1527 KParts::ReadWritePart * rw_part =
dynamic_cast<KParts::ReadWritePart*
>( partForURL( url ) );
1528 if ( !rw_part )
return Clean;
1530 DocumentState state = Clean;
1531 if ( rw_part->isModified() )
1536 if ( isDirty( url ) )
1538 if ( state == Modified )
1540 state = DirtyAndModified;
1551void PartController::doEmitState( KURL
const & url )
1553 emit documentChangedState( url, documentState( url ) );
1556KURL::List PartController::openURLs( )
1559 TQPtrListIterator<KParts::Part> it(*parts());
1560 for ( ; it.current(); ++it)
1562 if ( KParts::ReadOnlyPart *ro_part =
dynamic_cast<KParts::ReadOnlyPart*
>(it.current()) )
1564 list << ro_part->url();
1574PartController::HistoryEntry::HistoryEntry(
const KURL & u,
int l,
int c)
1575 : url(u), line(l), col(c)
1577 id = abs( TQTime::currentTime().msecsTo( TQTime() ) );
1580void PartController::slotBack()
1582 HistoryEntry thatEntry = m_backHistory.front();
1583 m_backHistory.pop_front();
1584 m_backAction->setEnabled( !m_backHistory.isEmpty() );
1586 HistoryEntry thisEntry = createHistoryEntry();
1587 if ( !thisEntry.url.isEmpty() )
1589 m_forwardHistory.push_front( thisEntry );
1590 m_forwardAction->setEnabled(
true );
1593 jumpTo( thatEntry );
1596void PartController::slotForward()
1598 HistoryEntry thatEntry = m_forwardHistory.front();
1599 m_forwardHistory.pop_front();
1600 m_forwardAction->setEnabled( !m_forwardHistory.isEmpty() );
1602 HistoryEntry thisEntry = createHistoryEntry();
1603 if ( !thisEntry.url.isEmpty() )
1605 m_backHistory.push_front( thisEntry );
1606 m_backAction->setEnabled(
true );
1609 jumpTo( thatEntry );
1612void PartController::slotBackAboutToShow()
1614 TDEPopupMenu *popup = m_backAction->popupMenu();
1617 if ( m_backHistory.isEmpty())
return;
1620 TQValueList<HistoryEntry>::ConstIterator it = m_backHistory.begin();
1621 while( i < 10 && it != m_backHistory.end() )
1623 popup->insertItem( (*it).url.fileName() + TQString(
" (%1)").arg( (*it).line +1), (*it).id );
1629void PartController::slotForwardAboutToShow( )
1631 TDEPopupMenu * popup = m_forwardAction->popupMenu();
1634 if ( m_forwardHistory.isEmpty() )
return;
1637 TQValueList<HistoryEntry>::ConstIterator it = m_forwardHistory.begin();
1638 while( i < 10 && it != m_forwardHistory.end() )
1640 popup->insertItem( (*it).url.fileName() + TQString(
" (%1)").arg( (*it).line +1), (*it).id );
1646void PartController::slotBackPopupActivated(
int id )
1648 TQValueList<HistoryEntry>::Iterator it = m_backHistory.begin();
1649 while( it != m_backHistory.end() )
1651 if ( (*it).id ==
id )
1653 HistoryEntry entry = *it;
1654 m_backHistory.erase( m_backHistory.begin(), ++it );
1655 m_backAction->setEnabled( !m_backHistory.isEmpty() );
1657 HistoryEntry thisEntry = createHistoryEntry();
1658 if ( !thisEntry.url.isEmpty() )
1660 m_forwardHistory.push_front( thisEntry );
1661 m_forwardAction->setEnabled(
true );
1671void PartController::slotForwardPopupActivated(
int id )
1673 TQValueList<HistoryEntry>::Iterator it = m_forwardHistory.begin();
1674 while( it != m_forwardHistory.end() )
1676 if ( (*it).id ==
id )
1678 HistoryEntry entry = *it;
1679 m_forwardHistory.erase( m_forwardHistory.begin(), ++it );
1680 m_forwardAction->setEnabled( !m_forwardHistory.isEmpty() );
1682 HistoryEntry thisEntry = createHistoryEntry();
1683 if ( !thisEntry.url.isEmpty() )
1685 m_backHistory.push_front( thisEntry );
1686 m_backAction->setEnabled(
true );
1696void PartController::jumpTo(
const HistoryEntry & entry )
1699 editDocument( entry.url, entry.line, entry.col );
1700 m_isJumping =
false;
1704PartController::HistoryEntry PartController::createHistoryEntry( KParts::ReadOnlyPart * ro_part ) {
1706 ro_part =
dynamic_cast<KParts::ReadOnlyPart*
>( activePart() );
1708 if ( !ro_part )
return HistoryEntry();
1709 KTextEditor::ViewCursorInterface * cursorIface =
dynamic_cast<KTextEditor::ViewCursorInterface*
>( ro_part->widget() );
1710 if ( !cursorIface )
return HistoryEntry();
1714 cursorIface->cursorPositionReal( &line, &col );
1716 return HistoryEntry( ro_part->url(), line, col );
1721void PartController::addHistoryEntry( KParts::ReadOnlyPart * part )
1723 if ( m_isJumping )
return;
1725 HistoryEntry thisEntry = createHistoryEntry( part );
1726 if ( !thisEntry.url.isEmpty() )
1728 HistoryEntry lastEntry = m_backHistory.front();
1729 if ( (lastEntry.url.path() != thisEntry.url.path()) || (lastEntry.line != thisEntry.line) )
1731 m_backHistory.push_front( thisEntry );
1732 m_backAction->setEnabled(
true );
1734 m_forwardHistory.clear();
1735 m_forwardAction->setEnabled(
false );
1739 kdDebug(9000) <<
"** avoiding to create duplicate history entry **" << endl;
1746void PartController::slotWaitForFactoryHack( )
1750 if ( !activePart() )
return;
1752 if (
dynamic_cast<KTextEditor::View*
>( activePart()->widget() ) )
1754 if ( !activePart()->factory() )
1756 TQTimer::singleShot( 100,
this, TQ_SLOT(slotWaitForFactoryHack()) );
1761 EditorProxy::getInstance()->installPopup( activePart() );
1765 if ( MultiBuffer *multiBuffer =
1766 dynamic_cast<MultiBuffer*
>(
1767 EditorProxy::getInstance()->topWidgetForPart( activePart() ) )
1770 KURL url =
dynamic_cast<KParts::ReadOnlyPart*
>( activePart() )->url();
1771 multiBuffer->activePartChanged( url );
1774 emit documentChangedState( url, documentState( url ) );
1778KParts::ReadOnlyPart *PartController::qtDesignerPart()
1780 TQPtrListIterator<KParts::Part> it(*parts());
1781 for ( ; it.current(); ++it)
1783 KInterfaceDesigner::Designer *des =
dynamic_cast<KInterfaceDesigner::Designer*
>(it.current());
1784 if (des && des->designerType() == KInterfaceDesigner::TQtDesigner)
1790KTextEditor::Editor *PartController::openTextDocument(
bool activate )
1792 KTextEditor::Editor *editorpart =
1793 createEditorPart( activate,
false, KURL( i18n(
"unnamed") ) );
1797 if ( !m_presetEncoding.isNull() )
1799 KParts::BrowserExtension * extension =
1800 KParts::BrowserExtension::childObject( editorpart );
1803 KParts::URLArgs args;
1804 args.serviceType = TQString(
"text/plain;" ) + m_presetEncoding;
1805 extension->setURLArgs(args);
1807 m_presetEncoding = TQString();
1811 EditorProxy::getInstance()->topWidgetForPart( editorpart );
1814 integratePart(editorpart, KURL(i18n(
"unnamed")), widget,
true,
true);
1816 EditorProxy::getInstance()->setLineNumber(editorpart, 0, 0);
1822void PartController::textChanged()
1824 if ( KTextEditor::Document * doc =
dynamic_cast<KTextEditor::Document*
>( activePart() ) )
1826 if ( KTextEditor::ViewCursorInterface * vci =
dynamic_cast<KTextEditor::ViewCursorInterface*
>( doc->widget() ) )
1828 m_gotoLastEditPosAction->setEnabled(
true );
1830 m_lastEditPos.url = doc->url();
1831 vci->cursorPosition( &m_lastEditPos.pos.first, &m_lastEditPos.pos.second );
1836void PartController::gotoLastEditPos()
1838 editDocument( m_lastEditPos.url, m_lastEditPos.pos.first, m_lastEditPos.pos.second );
1841void PartController::slotDocumentUrlChanged()
1843 TQObject *obj =
const_cast<TQObject*
>(sender());
1844 KTextEditor::Document *doc =
dynamic_cast<KTextEditor::Document*
>( obj );
1848 MultiBuffer *multiBuffer =
dynamic_cast<MultiBuffer*
>(
1849 EditorProxy::getInstance()->findPartWidget( doc ));
1853 multiBuffer->updateUrlForPart(doc, doc->url());
1855 emit partURLChanged(doc);
1858#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.