00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <qcheckbox.h>
00019 #include <qvbox.h>
00020 #include <qbuttongroup.h>
00021 #include <qradiobutton.h>
00022 #include <qdir.h>
00023 #include <qregexp.h>
00024
00025 #include <kaction.h>
00026 #include <kaboutdata.h>
00027 #include <kstdaction.h>
00028 #include <kapplication.h>
00029 #include <klocale.h>
00030 #include <kstatusbar.h>
00031 #include <kparts/mainwindow.h>
00032 #include <kdialogbase.h>
00033 #include <kconfig.h>
00034 #include <kkeydialog.h>
00035 #include <kmenubar.h>
00036 #include <kedittoolbar.h>
00037 #include <kbugreport.h>
00038 #include <kurlrequester.h>
00039 #include <kpopupmenu.h>
00040 #include <kiconloader.h>
00041
00042 #include <ktexteditor/document.h>
00043 #include <ktexteditor/view.h>
00044 #include <ktexteditor/configinterface.h>
00045 #include <kparts/partmanager.h>
00046 #include <kdeversion.h>
00047 #include <kdebug.h>
00048 #include <knotifydialog.h>
00049
00050
00051 #include <config.h>
00052
00053 #include "partcontroller.h"
00054 #include "projectmanager.h"
00055 #include "core.h"
00056 #include "settingswidget.h"
00057 #include "api.h"
00058 #include "kdevmakefrontend.h"
00059 #include "toplevel.h"
00060
00061 #include "mainwindowshare.h"
00062
00063 #ifdef KDE_MAKE_VERSION
00064 # if KDE_VERSION < KDE_MAKE_VERSION(3,1,90)
00065 # define NEED_CONFIGHACK
00066 # endif
00067 #else
00068 # define NEED_CONFIGHACK
00069 #endif
00070
00071 using namespace MainWindowUtils;
00072
00073 MainWindowShare::MainWindowShare(QObject* pParent, const char* name)
00074 :QObject(pParent, name)
00075 ,m_toggleMainToolbar(0L)
00076 ,m_toggleBuildToolbar(0L)
00077 ,m_toggleViewToolbar(0L)
00078 ,m_toggleBrowserToolbar(0L)
00079 ,m_toggleStatusbar(0L)
00080 ,m_stopProcesses(0L)
00081 {
00082 m_pMainWnd = (KParts::MainWindow*)pParent;
00083 }
00084
00085 void MainWindowShare::init()
00086 {
00087 connect(Core::getInstance(), SIGNAL(contextMenu(QPopupMenu *, const Context *)),
00088 this, SLOT(contextMenu(QPopupMenu *, const Context *)));
00089
00090 connect( m_pMainWnd->actionCollection(), SIGNAL( actionStatusText( const QString & ) ),
00091 this, SLOT( slotActionStatusText( const QString & ) ) );
00092 }
00093
00094 void MainWindowShare::slotActionStatusText( const QString &text )
00095 {
00096
00097
00098 if ( ! m_pMainWnd ) return;
00099
00100 KStatusBar * statusBar = m_pMainWnd->statusBar();
00101
00102 if ( ! statusBar ) return;
00103
00104 statusBar->message( text );
00105 }
00106
00107 void MainWindowShare::createActions()
00108 {
00109 ProjectManager::getInstance()->createActions( m_pMainWnd->actionCollection() );
00110
00111 KStdAction::quit(this->parent(), SLOT(close()), m_pMainWnd->actionCollection());
00112
00113 KAction* action;
00114
00115 m_stopProcesses = new KToolBarPopupAction( i18n( "&Stop" ), "stop",
00116 Key_Escape, this, SLOT(slotStopButtonPressed()),
00117 m_pMainWnd->actionCollection(), "stop_processes" );
00118 m_stopProcesses->setToolTip(i18n("Stop"));
00119 m_stopProcesses->setWhatsThis(i18n("<b>Stop</b><p>Stops all running processes (like building process, grep command, etc.). When placed onto a toolbar provides a popup menu to choose a process to stop."));
00120 m_stopProcesses->setEnabled( false );
00121 connect(m_stopProcesses->popupMenu(), SIGNAL(aboutToShow()),
00122 this, SLOT(slotStopMenuAboutToShow()));
00123 connect(m_stopProcesses->popupMenu(), SIGNAL(activated(int)),
00124 this, SLOT(slotStopPopupActivated(int)));
00125
00126 connect( Core::getInstance(), SIGNAL(activeProcessChanged(KDevPlugin*, bool)),
00127 this, SLOT(slotActiveProcessChanged(KDevPlugin*, bool)) );
00128
00129 action = KStdAction::showMenubar(
00130 this, SLOT(slotShowMenuBar()),
00131 m_pMainWnd->actionCollection(), "settings_show_menubar" );
00132 action->setToolTip(beautifyToolTip(action->text()));
00133 action->setWhatsThis(QString("<b>%1</b><p>%2").arg(beautifyToolTip(action->text())).arg(i18n("Lets you switch the menubar on/off.")));
00134
00135 action = KStdAction::keyBindings(
00136 this, SLOT(slotKeyBindings()),
00137 m_pMainWnd->actionCollection(), "settings_configure_shortcuts" );
00138 action->setToolTip(beautifyToolTip(action->text()));
00139 action->setWhatsThis(QString("<b>%1</b><p>%2").arg(beautifyToolTip(action->text())).arg(i18n("Lets you configure shortcut keys.")));
00140
00141 action = KStdAction::configureToolbars(
00142 this, SLOT(slotConfigureToolbars()),
00143 m_pMainWnd->actionCollection(), "settings_configure_toolbars" );
00144 action->setToolTip(beautifyToolTip(action->text()));
00145 action->setWhatsThis(QString("<b>%1</b><p>%2").arg(beautifyToolTip(action->text())).arg(i18n("Lets you configure toolbars.")));
00146
00147 action = KStdAction::configureNotifications(
00148 this, SLOT(slotConfigureNotifications()),
00149 m_pMainWnd->actionCollection(), "settings_configure_notifications" );
00150 action->setToolTip(beautifyToolTip(action->text()));
00151 action->setWhatsThis(QString("<b>%1</b><p>%2").arg(beautifyToolTip(action->text())).arg(i18n("Lets you configure system notifications.")));
00152
00153 action = KStdAction::preferences(this, SLOT(slotSettings()),
00154 m_pMainWnd->actionCollection(), "settings_configure" );
00155 action->setToolTip(beautifyToolTip(action->text()));
00156 action->setWhatsThis(QString("<b>%1</b><p>%2").arg(beautifyToolTip(action->text())).arg(i18n("Lets you customize KDevelop.")));
00157
00158 m_toggleStatusbar = KStdAction::showToolbar(this, SLOT(slotToggleStatusbar()),m_pMainWnd->actionCollection(), "settings_statusbar");
00159 m_toggleStatusbar->setText(i18n("Show &Statusbar"));
00160 m_toggleStatusbar->setToolTip( i18n("Show statusbar") );
00161 m_toggleStatusbar->setWhatsThis(i18n("<b>Show statusbar</b><p>Hides or shows the statusbar."));
00162
00163 action = new KAction( i18n("&Next Window"), ALT+Key_Right, this, SIGNAL(gotoNextWindow()),m_pMainWnd->actionCollection(), "view_next_window");
00164 action->setToolTip( i18n("Next window") );
00165 action->setWhatsThis(i18n("<b>Next window</b><p>Switches to the next window."));
00166
00167 action = new KAction( i18n("&Previous Window"), ALT+Key_Left, this, SIGNAL(gotoPreviousWindow()),m_pMainWnd->actionCollection(), "view_previous_window");
00168 action->setToolTip( i18n("Previous window") );
00169 action->setWhatsThis(i18n("<b>Previous window</b><p>Switches to the previous window."));
00170
00171 action = new KAction( i18n("&Last Accessed Window"), ALT+Key_Up, this, SIGNAL(gotoLastWindow()), m_pMainWnd->actionCollection(), "view_last_window");
00172 action->setToolTip( i18n("Last accessed window") );
00173 action->setWhatsThis(i18n("<b>Last accessed window</b><p>Switches to the last viewed window (Hold the Alt key pressed and walk on by repeating the Up key)."));
00174
00175 action = new KAction( i18n("&First Accessed Window"), ALT+Key_Down, this, SIGNAL(gotoFirstWindow()), m_pMainWnd->actionCollection(), "view_first_window");
00176 action->setToolTip( i18n("First accessed window") );
00177 action->setWhatsThis(i18n("<b>First accessed window</b><p>Switches to the first accessed window (Hold the Alt key pressed and walk on by repeating the Down key)."));
00178
00179 m_configureEditorAction = new KAction( i18n("Configure &Editor..."), 0, this, SLOT( slotConfigureEditors() ), m_pMainWnd->actionCollection(), "settings_configure_editors");
00180 m_configureEditorAction->setToolTip( i18n("Configure editor settings") );
00181 m_configureEditorAction->setWhatsThis(i18n("<b>Configure editor</b><p>Opens editor configuration dialog."));
00182 m_configureEditorAction->setEnabled( false );
00183
00184 KDevPartController * partController = API::getInstance()->partController();
00185 connect( partController, SIGNAL(activePartChanged(KParts::Part*)), this, SLOT(slotActivePartChanged(KParts::Part* )) );
00186 }
00187
00188 void MainWindowShare::slotReportBug()
00189 {
00190 KBugReport a(m_pMainWnd, true, KGlobal::instance()->aboutData() );
00191 a.exec();
00192 }
00193
00194 void MainWindowShare::slotToggleMainToolbar()
00195 {
00196 if (m_toggleMainToolbar->isChecked())
00197 m_pMainWnd->toolBar("mainToolBar")->show();
00198 else
00199 m_pMainWnd->toolBar("mainToolBar")->hide();
00200 }
00201
00202 void MainWindowShare::slotToggleBuildToolbar()
00203 {
00204 if (m_toggleBuildToolbar->isChecked())
00205 m_pMainWnd->toolBar("buildToolBar")->show();
00206 else
00207 m_pMainWnd->toolBar("buildToolBar")->hide();
00208 }
00209
00210 void MainWindowShare::slotToggleViewToolbar()
00211 {
00212 if (m_toggleViewToolbar->isChecked())
00213 m_pMainWnd->toolBar("viewToolBar")->show();
00214 else
00215 m_pMainWnd->toolBar("viewToolBar")->hide();
00216 }
00217
00218 void MainWindowShare::slotToggleBrowserToolbar()
00219 {
00220 if (m_toggleBrowserToolbar->isChecked())
00221 m_pMainWnd->toolBar("browserToolBar")->show();
00222 else
00223 m_pMainWnd->toolBar("browserToolBar")->hide();
00224 }
00225
00226 void MainWindowShare::slotToggleStatusbar()
00227 {
00228 KStatusBar* sb = (KStatusBar*) m_pMainWnd->statusBar();
00229 if (m_toggleStatusbar->isChecked())
00230 sb->show();
00231 else
00232 sb->hide();
00233 }
00234
00235 void MainWindowShare::slotStopButtonPressed()
00236 {
00237 Core::getInstance()->doEmitStopButtonPressed();
00238 }
00239
00240 void MainWindowShare::slotActiveProcessChanged( KDevPlugin* plugin, bool active )
00241 {
00242 if ( !plugin )
00243 return;
00244
00245 if ( active ) {
00246 activeProcesses.append( plugin );
00247 } else {
00248 activeProcesses.removeRef( plugin );
00249 }
00250 m_stopProcesses->setEnabled( !activeProcesses.isEmpty() );
00251 }
00252
00253 void MainWindowShare::slotStopPopupActivated( int id )
00254 {
00255 KDevPlugin* plugin = activeProcesses.at( id );
00256 if ( plugin && plugin->pluginName() == m_stopProcesses->popupMenu()->text( id ) ) {
00257 Core::getInstance()->doEmitStopButtonPressed( plugin );
00258 return;
00259 } else {
00260
00261 QString str = m_stopProcesses->popupMenu()->text( id );
00262 for ( plugin = activeProcesses.first(); plugin; plugin = activeProcesses.next() ) {
00263 if ( plugin->pluginName() == str ) {
00264 Core::getInstance()->doEmitStopButtonPressed( plugin );
00265 return;
00266 }
00267 }
00268 }
00269 }
00270
00271 void MainWindowShare::slotStopMenuAboutToShow()
00272 {
00273 QPopupMenu* popup = m_stopProcesses->popupMenu();
00274 popup->clear();
00275
00276 int i = 0;
00277 for ( KDevPlugin* plugin = activeProcesses.first(); plugin; plugin = activeProcesses.next() ) {
00278 popup->insertItem( plugin->pluginName(), i++ );
00279 }
00280 }
00281
00282 void MainWindowShare::slotShowMenuBar()
00283 {
00284 if (m_pMainWnd->menuBar()->isVisible()) {
00285 m_pMainWnd->menuBar()->hide();
00286 } else {
00287 m_pMainWnd->menuBar()->show();
00288 }
00289 m_pMainWnd->saveMainWindowSettings( KGlobal::config(), "Mainwindow" );
00290 }
00291
00292 void MainWindowShare::slotConfigureNotifications()
00293 {
00294 KNotifyDialog::configure(m_pMainWnd, "Notification Configuration Dialog");
00295 }
00296
00297 void MainWindowShare::slotSettings()
00298 {
00299 KDialogBase dlg(KDialogBase::IconList, i18n("Configure KDevelop"),
00300 KDialogBase::Help|KDialogBase::Ok|KDialogBase::Cancel, KDialogBase::Ok, m_pMainWnd,
00301 "customization dialog");
00302
00303 SettingsWidget *gsw;
00304 KConfig* config = kapp->config();
00305 if (TopLevel::mode != TopLevel::AssistantMode)
00306 {
00307 dlg.setHelp("setup");
00308 QVBox *vbox = dlg.addVBoxPage(i18n("General"), i18n("General"), DesktopIcon("kdevelop") );
00309 gsw = new SettingsWidget(vbox, "general settings widget");
00310
00311 gsw->projects_url->setMode((int)KFile::Directory);
00312
00313 config->setGroup("General Options");
00314 gsw->lastProjectCheckbox->setChecked(config->readBoolEntry("Read Last Project On Startup",true));
00315 config->setGroup("MakeOutputView");
00316 gsw->setMessageFont(config->readFontEntry("Messages Font"));
00317 gsw->lineWrappingCheckBox->setChecked(config->readBoolEntry("LineWrapping",true));
00318 gsw->dirNavigMsgCheckBox->setChecked(config->readBoolEntry("ShowDirNavigMsg",false));
00319 gsw->compilerOutputButtonGroup->setRadioButtonExclusive(true);
00320 gsw->compilerOutputButtonGroup->setButton(config->readNumEntry("CompilerOutputLevel",0));
00321 config->setGroup("General Options");
00322 gsw->setApplicationFont(config->readFontEntry("Application Font"));
00323 gsw->changeMessageFontButton->setText(gsw->messageFont().family());
00324 gsw->changeMessageFontButton->setFont(gsw->messageFont());
00325 gsw->changeApplicationFontButton->setText(gsw->applicationFont().family());
00326 gsw->changeApplicationFontButton->setFont(gsw->applicationFont());
00327 gsw->projects_url->setURL(config->readPathEntry("DefaultProjectsDir", QDir::homeDirPath()+"/"));
00328 gsw->embedDesignerCheckBox->setChecked(config->readBoolEntry("Embed KDevDesigner", true));
00329 }
00330
00331 config->setGroup("Global Settings Dialog");
00332 int height = config->readNumEntry( "Height", 600 );
00333 int width = config->readNumEntry( "Width", 800 );
00334
00335 dlg.resize( width, height );
00336
00337 Core::getInstance()->doEmitConfigWidget(&dlg);
00338 dlg.exec();
00339
00340 config->setGroup("Global Settings Dialog");
00341 config->writeEntry( "Height", dlg.size().height() );
00342 config->writeEntry( "Width", dlg.size().width() );
00343
00344 if (TopLevel::mode != TopLevel::AssistantMode)
00345 {
00346 config->setGroup("General Options");
00347 config->writeEntry("Embed KDevDesigner", gsw->embedDesignerCheckBox->isChecked());
00348 config->writeEntry("Read Last Project On Startup",gsw->lastProjectCheckbox->isChecked());
00349 config->writePathEntry("DefaultProjectsDir", gsw->projects_url->url());
00350 config->writeEntry("Application Font", gsw->applicationFont());
00351 config->setGroup("MakeOutputView");
00352 config->writeEntry("Messages Font",gsw->messageFont());
00353 config->writeEntry("LineWrapping",gsw->lineWrappingCheckBox->isChecked());
00354 config->writeEntry("ShowDirNavigMsg",gsw->dirNavigMsgCheckBox->isChecked());
00355 QButton* pSelButton = gsw->compilerOutputButtonGroup->selected();
00356 config->writeEntry("CompilerOutputLevel",gsw->compilerOutputButtonGroup->id(pSelButton));
00357 config->sync();
00358 if( API::getInstance()->makeFrontend() )
00359 API::getInstance()->makeFrontend()->updateSettingsFromConfig();
00360 }
00361 }
00362
00363 void MainWindowShare::slotConfigureEditors()
00364 {
00365 kdDebug(9000) << " *** MainWindowShare::slotConfigureEditors()" << endl;
00366
00367 KDevPartController * partController = API::getInstance()->partController();
00368 KParts::Part * part = partController->activePart();
00369
00370 KTextEditor::ConfigInterface * conf = dynamic_cast<KTextEditor::ConfigInterface*>( part );
00371 if ( ! conf )
00372 {
00373 kdDebug(9000) << "*** No KTextEditor::ConfigInterface for part!" << endl;
00374 return;
00375 }
00376
00377
00378 conf->configDialog();
00379 conf->writeConfig();
00380
00381 #ifdef NEED_CONFIGHACK
00382
00383 if( const QPtrList<KParts::Part> * partlist = partController->parts() )
00384 {
00385 QPtrListIterator<KParts::Part> it( *partlist );
00386 while ( KParts::Part* p = it.current() )
00387 {
00388 if ( KTextEditor::ConfigInterface * ci = dynamic_cast<KTextEditor::ConfigInterface *>( p ) )
00389 {
00390 ci->readConfig();
00391 }
00392 ++it;
00393 }
00394 }
00395 #endif
00396 }
00397
00398 void MainWindowShare::slotGUICreated( KParts::Part * part )
00399 {
00400
00401
00402 if ( ! part ) return;
00403
00404
00405 if ( ! dynamic_cast<KTextEditor::ConfigInterface *>( part ) )
00406 {
00407 m_configureEditorAction->setEnabled( false );
00408 return;
00409 }
00410
00411 m_configureEditorAction->setEnabled( true );
00412
00413
00414 KAction * action = part->action("set_confdlg");
00415 if ( action )
00416 {
00417 kdDebug(9000) << " *** found \"set_confdlg\" action - unplugging" << endl;
00418 action->unplugAll();
00419 }
00420
00421 if ( KAction * action = part->action("file_save") )
00422 {
00423 kdDebug(9000) << " *** found \"file_save\" action - disconnecting" << endl;
00424 disconnect( action, SIGNAL(activated()), 0, 0 );
00425 connect( action, SIGNAL(activated()), PartController::getInstance(), SLOT(slotSave()) );
00426 }
00427
00428 if ( KAction * action = part->action("file_reload") )
00429 {
00430 kdDebug(9000) << " *** found \"file_reload\" action - disconnecting" << endl;
00431 disconnect( action, SIGNAL(activated()), 0, 0 );
00432 connect( action, SIGNAL(activated()), PartController::getInstance(), SLOT(slotReload()) );
00433 }
00434 }
00435
00436
00437 void MainWindowShare::slotNewToolbarConfig()
00438 {
00439
00440
00441 m_pMainWnd->applyMainWindowSettings( KGlobal::config(), "Mainwindow" );
00442
00443
00444 }
00445
00446 void MainWindowShare::slotKeyBindings()
00447 {
00448 KKeyDialog dlg( false, m_pMainWnd );
00449 QPtrList<KXMLGUIClient> clients = m_pMainWnd->guiFactory()->clients();
00450 for( QPtrListIterator<KXMLGUIClient> it( clients );
00451 it.current(); ++it ) {
00452 dlg.insert( (*it)->actionCollection() );
00453 }
00454 if ( dlg.configure() == KKeyDialog::Accepted )
00455 {
00456
00457
00458 if( const QPtrList<KParts::Part> * partlist = PartController::getInstance()->parts() )
00459 {
00460 QPtrListIterator<KParts::Part> it( *partlist );
00461 while ( KParts::Part* part = it.current() )
00462 {
00463 if ( KTextEditor::Document * doc = dynamic_cast<KTextEditor::Document*>( part ) )
00464 {
00465 doc->reloadXML();
00466
00467 QPtrList<KTextEditor::View> const & list = doc->views();
00468 QPtrListIterator<KTextEditor::View> itt( list );
00469 while( KTextEditor::View * view = itt.current() )
00470 {
00471 view->reloadXML();
00472 ++itt;
00473 }
00474 }
00475 ++it;
00476 }
00477 }
00478 }
00479 }
00480
00481 void MainWindowShare::slotConfigureToolbars()
00482 {
00483 m_pMainWnd->saveMainWindowSettings( KGlobal::config(), "Mainwindow" );
00484 KEditToolbar dlg( m_pMainWnd->factory() );
00485 connect(&dlg, SIGNAL(newToolbarConfig()), this, SLOT(slotNewToolbarConfig()));
00486 dlg.exec();
00487 }
00488
00489 void MainWindowShare::contextMenu(QPopupMenu* popup, const Context *)
00490 {
00491 if ( m_pMainWnd->menuBar()->isVisible() )
00492 return;
00493
00494 int id = popup->insertItem( i18n("Show &Menubar"), m_pMainWnd->menuBar(), SLOT(show()) );
00495 popup->setWhatsThis(id, i18n("<b>Show menubar</b><p>Lets you switch the menubar on/off."));
00496 }
00497
00498 void MainWindowShare::slotActivePartChanged( KParts::Part * part )
00499 {
00500 m_configureEditorAction->setEnabled( part && dynamic_cast<KTextEditor::Document*>(part) );
00501 }
00502
00503 #include "mainwindowshare.moc"