1
/* This file is part of the KDE project
2
Copyright (C) 2001 Christoph Cullmann <cullmann@kde.org>
3
Copyright (C) 2001 Joseph Wenninger <jowenn@kde.org>
4
Copyright (C) 2001 Anders Lund <anders.lund@lund.tdcadsl.dk>
5
Copyright (C) 2007 Flavio Castelli <flavio.castelli@gmail.com>
7
This library is free software; you can redistribute it and/or
8
modify it under the terms of the GNU Library General Public
9
License version 2 as published by the Free Software Foundation.
11
This library is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
Library General Public License for more details.
16
You should have received a copy of the GNU Library General Public License
17
along with this library; see the file COPYING.LIB. If not, write to
18
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19
Boston, MA 02110-1301, USA.
23
#include "katemainwindow.h"
25
#include "kateconfigdialog.h"
26
#include "katedocmanager.h"
27
#include "katepluginmanager.h"
28
#include "kateconfigplugindialogpage.h"
29
#include "kateviewmanager.h"
31
#include "katesavemodifieddialog.h"
32
#include "katemwmodonhddialog.h"
33
#include "katesessionsaction.h"
34
#include "katesessionmanager.h"
35
#include "kateviewspace.h"
36
#include "katequickopen.h"
37
#include "kateupdatedisabler.h"
38
#include "katedebug.h"
40
#include <KActionMenu>
41
#include <KAboutApplicationDialog>
42
#include <KEditToolBar>
43
#include <KShortcutsDialog>
44
#include <KMessageBox>
45
#include <KOpenWithDialog>
46
#include <KStandardAction>
47
#include <KMimeTypeTrader>
48
#include <KMultiTabBar>
49
#include <khelpclient.h>
51
#include <KRecentFilesAction>
52
#include <KToggleFullScreenAction>
53
#include <KActionCollection>
55
#include <KWindowSystem>
57
#include <KLocalizedString>
58
#include <KConfigGroup>
59
#include <KSharedConfig>
60
#include <kwindowconfig.h>
61
#include <KXMLGUIFactory>
66
#include <QDesktopWidget>
70
#include <QMimeDatabase>
71
#include <QDragEnterEvent>
73
#include <QApplication>
76
#include <QToolButton>
78
#include <QFontDatabase>
80
#include <ktexteditor/sessionconfiginterface.h>
83
KateMwModOnHdDialog *KateMainWindow::s_modOnHdDialog = 0;
85
KateContainerStackedLayout::KateContainerStackedLayout(QWidget *parent)
86
: QStackedLayout(parent)
89
QSize KateContainerStackedLayout::sizeHint() const
91
if (currentWidget()) {
92
return currentWidget()->sizeHint();
94
return QStackedLayout::sizeHint();
97
QSize KateContainerStackedLayout::minimumSize() const
99
if (currentWidget()) {
100
return currentWidget()->minimumSize();
102
return QStackedLayout::minimumSize();
105
KateMainWindow::KateMainWindow(KConfig *sconfig, const QString &sgroup)
106
: KateMDI::MainWindow(0)
108
, m_wrapper(new KTextEditor::MainWindow(this))
111
* we don't want any flicker here
113
KateUpdateDisabler disableUpdates (this);
116
* get and set config revision
118
static const int currentConfigRevision = 10;
119
const int readConfigRevision = KConfigGroup(KSharedConfig::openConfig(), "General").readEntry("Config Revision", 0);
120
KConfigGroup(KSharedConfig::openConfig(), "General").writeEntry("Config Revision", currentConfigRevision);
121
const bool firstStart = readConfigRevision < currentConfigRevision;
123
// start session restore if needed
124
startRestore(sconfig, sgroup);
126
// setup most important actions first, needed by setupMainWindow
127
setupImportantActions();
129
// setup the most important widgets
135
setStandardToolBarMenuEnabled(true);
136
setXMLFile(QStringLiteral("kateui.rc"));
137
createShellGUI(true);
139
//qCDebug(LOG_KATE) << "****************************************************************************" << sconfig;
141
// register mainwindow in app
142
KateApp::self()->addMainWindow(this);
144
// enable plugin guis
145
KateApp::self()->pluginManager()->enableAllPluginsGUI(this, sconfig);
148
Q_FOREACH (auto doc, KateApp::self()->documentManager()->documentList()) {
149
slotDocumentCreated(doc);
152
connect(KateApp::self()->documentManager(), SIGNAL(documentCreated(KTextEditor::Document*)), this, SLOT(slotDocumentCreated(KTextEditor::Document*)));
157
m_viewManager->restoreViewConfiguration(KConfigGroup(sconfig, sgroup));
162
m_fileOpenRecent->loadEntries(KConfigGroup(sconfig, "Recent Files"));
164
setAcceptDrops(true);
166
connect(KateApp::self()->sessionManager(), SIGNAL(sessionChanged()), this, SLOT(updateCaption()));
168
connect(this, SIGNAL(sigShowPluginConfigPage(KTextEditor::Plugin*,uint)), this, SLOT(showPluginConfigPage(KTextEditor::Plugin*,uint)));
170
// prior to this there was (possibly) no view, therefore not context menu.
171
// Hence, we have to take care of the menu bar here
172
toggleShowMenuBar(false);
174
// on first start: deactivate toolbar
176
toolBar(QLatin1String("mainToolBar"))->hide();
179
KateMainWindow::~KateMainWindow()
181
// first, save our fallback window size ;)
182
KConfigGroup cfg(KSharedConfig::openConfig(), "MainWindow");
183
KWindowConfig::saveWindowSize(windowHandle(), cfg);
185
// save other options ;=)
188
// unregister mainwindow in app
189
KateApp::self()->removeMainWindow(this);
191
// disable all plugin guis, delete all pluginViews
192
KateApp::self()->pluginManager()->disableAllPluginsGUI(this);
194
// delete the view manager, before KateMainWindow's wrapper is dead
195
delete m_viewManager;
198
// kill the wrapper object, now that all views are dead
203
QSize KateMainWindow::sizeHint() const
206
* have some useful size hint, else we have mini windows per default
208
return (QSize(640, 480).expandedTo(minimumSizeHint()));
211
void KateMainWindow::setupImportantActions()
213
m_paShowStatusBar = KStandardAction::showStatusbar(this, SLOT(toggleShowStatusBar()), actionCollection());
214
m_paShowStatusBar->setWhatsThis(i18n("Use this command to show or hide the view's statusbar"));
215
m_paShowMenuBar = KStandardAction::showMenubar(this, SLOT(toggleShowMenuBar()), actionCollection());
217
m_paShowTabBar = new KToggleAction(i18n("Show &Tabs"), this);
218
actionCollection()->addAction(QStringLiteral("settings_show_tab_bar"), m_paShowTabBar);
219
connect(m_paShowTabBar, SIGNAL(toggled(bool)), this, SLOT(toggleShowTabBar()));
220
m_paShowTabBar->setWhatsThis(i18n("Use this command to show or hide the tabs for the views"));
222
m_paShowPath = new KToggleAction(i18n("Sho&w Path in Titlebar"), this);
223
actionCollection()->addAction(QStringLiteral("settings_show_full_path"), m_paShowPath);
224
connect(m_paShowPath, SIGNAL(toggled(bool)), this, SLOT(updateCaption()));
225
m_paShowPath->setWhatsThis(i18n("Show the complete document path in the window caption"));
227
QAction * a = actionCollection()->addAction(KStandardAction::Back, QStringLiteral("view_prev_tab"));
228
a->setText(i18n("&Previous Tab"));
229
a->setWhatsThis(i18n("Focus the previous tab."));
230
connect(a, SIGNAL(triggered()), this, SLOT(slotFocusPrevTab()));
232
a = actionCollection()->addAction(KStandardAction::Forward, QStringLiteral("view_next_tab"));
233
a->setText(i18n("&Next Tab"));
234
a->setWhatsThis(i18n("Focus the next tab."));
235
connect(a, SIGNAL(triggered()), this, SLOT(slotFocusNextTab()));
237
// the quick open action is used by the KateViewSpace "quick open button"
238
a = actionCollection()->addAction(QStringLiteral("view_quick_open"));
239
a->setIcon(QIcon::fromTheme(QStringLiteral("quickopen")));
240
a->setText(i18n("&Quick Open"));
241
actionCollection()->setDefaultShortcut(a, QKeySequence(Qt::CTRL + Qt::ALT + Qt::Key_O));
242
connect(a, SIGNAL(triggered()), this, SLOT(slotQuickOpen()));
243
a->setWhatsThis(i18n("Open a form to quick open documents."));
246
void KateMainWindow::setupMainWindow()
248
setToolViewStyle(KMultiTabBar::KDEV3ICON);
251
* create central stacked widget with its children
253
m_mainStackedWidget = new QStackedWidget(centralWidget());
254
centralWidget()->layout()->addWidget(m_mainStackedWidget);
255
(static_cast<QBoxLayout *>(centralWidget()->layout()))->setStretchFactor(m_mainStackedWidget, 100);
257
m_quickOpen = new KateQuickOpen(m_mainStackedWidget, this);
258
m_mainStackedWidget->addWidget(m_quickOpen);
260
m_viewManager = new KateViewManager(m_mainStackedWidget, this);
261
m_mainStackedWidget->addWidget(m_viewManager);
263
// make view manager default visible!
264
m_mainStackedWidget->setCurrentWidget(m_viewManager);
266
m_bottomViewBarContainer = new QWidget(centralWidget());
267
centralWidget()->layout()->addWidget(m_bottomViewBarContainer);
268
m_bottomContainerStack = new KateContainerStackedLayout(m_bottomViewBarContainer);
271
void KateMainWindow::setupActions()
275
actionCollection()->addAction(KStandardAction::New, QStringLiteral("file_new"), m_viewManager, SLOT(slotDocumentNew()))
276
->setWhatsThis(i18n("Create a new document"));
277
actionCollection()->addAction(KStandardAction::Open, QStringLiteral("file_open"), m_viewManager, SLOT(slotDocumentOpen()))
278
->setWhatsThis(i18n("Open an existing document for editing"));
280
m_fileOpenRecent = KStandardAction::openRecent(m_viewManager, SLOT(openUrl(QUrl)), this);
281
m_fileOpenRecent->setMaxItems(KateConfigDialog::recentFilesMaxCount());
282
actionCollection()->addAction(m_fileOpenRecent->objectName(), m_fileOpenRecent);
283
m_fileOpenRecent->setWhatsThis(i18n("This lists files which you have opened recently, and allows you to easily open them again."));
285
a = actionCollection()->addAction(QStringLiteral("file_save_all"));
286
a->setIcon(QIcon::fromTheme(QStringLiteral("document-save-all")));
287
a->setText(i18n("Save A&ll"));
288
actionCollection()->setDefaultShortcut(a, QKeySequence(Qt::CTRL + Qt::Key_L));
289
connect(a, SIGNAL(triggered()), KateApp::self()->documentManager(), SLOT(saveAll()));
290
a->setWhatsThis(i18n("Save all open, modified documents to disk."));
292
a = actionCollection()->addAction(QStringLiteral("file_reload_all"));
293
a->setText(i18n("&Reload All"));
294
connect(a, SIGNAL(triggered()), KateApp::self()->documentManager(), SLOT(reloadAll()));
295
a->setWhatsThis(i18n("Reload all open documents."));
297
a = actionCollection()->addAction(QStringLiteral("file_close_orphaned"));
298
a->setText(i18n("Close Orphaned"));
299
connect(a, SIGNAL(triggered()), KateApp::self()->documentManager(), SLOT(closeOrphaned()));
300
a->setWhatsThis(i18n("Close all documents in the file list that could not be reopened, because they are not accessible anymore."));
302
actionCollection()->addAction(KStandardAction::Close, QStringLiteral("file_close"), m_viewManager, SLOT(slotDocumentClose()))
303
->setWhatsThis(i18n("Close the current document."));
305
a = actionCollection()->addAction(QStringLiteral("file_close_other"));
306
a->setText(i18n("Close Other"));
307
connect(a, SIGNAL(triggered()), this, SLOT(slotDocumentCloseOther()));
308
a->setWhatsThis(i18n("Close other open documents."));
310
a = actionCollection()->addAction(QStringLiteral("file_close_all"));
311
a->setText(i18n("Clos&e All"));
312
connect(a, SIGNAL(triggered()), this, SLOT(slotDocumentCloseAll()));
313
a->setWhatsThis(i18n("Close all open documents."));
315
a = actionCollection()->addAction(KStandardAction::Quit, QStringLiteral("file_quit"));
316
// Qt::QueuedConnection: delay real shutdown, as we are inside menu action handling (bug #185708)
317
connect(a, SIGNAL(triggered()), this, SLOT(slotFileQuit()), Qt::QueuedConnection);
318
a->setWhatsThis(i18n("Close this window"));
320
a = actionCollection()->addAction(QStringLiteral("view_new_view"));
321
a->setIcon(QIcon::fromTheme(QStringLiteral("window-new")));
322
a->setText(i18n("&New Window"));
323
connect(a, SIGNAL(triggered()), this, SLOT(newWindow()));
324
a->setWhatsThis(i18n("Create a new Kate view (a new window with the same document list)."));
326
m_showFullScreenAction = KStandardAction::fullScreen(0, 0, this, this);
327
actionCollection()->addAction(m_showFullScreenAction->objectName(), m_showFullScreenAction);
328
connect(m_showFullScreenAction, SIGNAL(toggled(bool)), this, SLOT(slotFullScreen(bool)));
330
documentOpenWith = new KActionMenu(i18n("Open W&ith"), this);
331
actionCollection()->addAction(QStringLiteral("file_open_with"), documentOpenWith);
332
documentOpenWith->setWhatsThis(i18n("Open the current document using another application registered for its file type, or an application of your choice."));
333
connect(documentOpenWith->menu(), SIGNAL(aboutToShow()), this, SLOT(mSlotFixOpenWithMenu()));
334
connect(documentOpenWith->menu(), SIGNAL(triggered(QAction*)), this, SLOT(slotOpenWithMenuAction(QAction*)));
336
a = KStandardAction::keyBindings(this, SLOT(editKeys()), actionCollection());
337
a->setWhatsThis(i18n("Configure the application's keyboard shortcut assignments."));
339
a = KStandardAction::configureToolbars(this, SLOT(slotEditToolbars()), actionCollection());
340
a->setWhatsThis(i18n("Configure which items should appear in the toolbar(s)."));
342
QAction *settingsConfigure = KStandardAction::preferences(this, SLOT(slotConfigure()), actionCollection());
343
settingsConfigure->setWhatsThis(i18n("Configure various aspects of this application and the editing component."));
345
if (KateApp::self()->pluginManager()->pluginList().count() > 0) {
346
a = actionCollection()->addAction(QStringLiteral("help_plugins_contents"));
347
a->setText(i18n("&Plugins Handbook"));
348
connect(a, SIGNAL(triggered()), this, SLOT(pluginHelp()));
349
a->setWhatsThis(i18n("This shows help files for various available plugins."));
352
a = actionCollection()->addAction(QStringLiteral("help_about_editor"));
353
a->setText(i18n("&About Editor Component"));
354
connect(a, SIGNAL(triggered()), this, SLOT(aboutEditor()));
356
connect(m_viewManager, SIGNAL(viewChanged(KTextEditor::View*)), this, SLOT(slotWindowActivated()));
357
connect(m_viewManager, SIGNAL(viewChanged(KTextEditor::View*)), this, SLOT(slotUpdateOpenWith()));
358
connect(m_viewManager, SIGNAL(viewChanged(KTextEditor::View*)), this, SLOT(slotUpdateBottomViewBar()));
360
// re-route signals to our wrapper
361
connect(m_viewManager, SIGNAL(viewChanged(KTextEditor::View*)), m_wrapper, SIGNAL(viewChanged(KTextEditor::View*)));
362
connect(m_viewManager, SIGNAL(viewCreated(KTextEditor::View*)), m_wrapper, SIGNAL(viewCreated(KTextEditor::View*)));
363
connect(this, SIGNAL(unhandledShortcutOverride(QEvent*)), m_wrapper, SIGNAL(unhandledShortcutOverride(QEvent*)));
365
slotWindowActivated();
368
a = actionCollection()->addAction(QStringLiteral("sessions_new"));
369
a->setIcon(QIcon::fromTheme(QStringLiteral("document-new")));
370
a->setText(i18nc("Menu entry Session->New", "&New"));
371
// Qt::QueuedConnection to avoid deletion of code that is executed when reducing the amount of mainwindows. (bug #227008)
372
connect(a, SIGNAL(triggered()), KateApp::self()->sessionManager(), SLOT(sessionNew()), Qt::QueuedConnection);
373
a = actionCollection()->addAction(QStringLiteral("sessions_open"));
374
a->setIcon(QIcon::fromTheme(QStringLiteral("document-open")));
375
a->setText(i18n("&Open Session"));
376
// Qt::QueuedConnection to avoid deletion of code that is executed when reducing the amount of mainwindows. (bug #227008)
377
connect(a, SIGNAL(triggered()), KateApp::self()->sessionManager(), SLOT(sessionOpen()), Qt::QueuedConnection);
378
a = actionCollection()->addAction(QStringLiteral("sessions_save"));
379
a->setIcon(QIcon::fromTheme(QStringLiteral("document-save")));
380
a->setText(i18n("&Save Session"));
381
connect(a, SIGNAL(triggered()), KateApp::self()->sessionManager(), SLOT(sessionSave()));
382
a = actionCollection()->addAction(QStringLiteral("sessions_save_as"));
383
a->setIcon(QIcon::fromTheme(QStringLiteral("document-save-as")));
384
a->setText(i18n("Save Session &As..."));
385
connect(a, SIGNAL(triggered()), KateApp::self()->sessionManager(), SLOT(sessionSaveAs()));
386
a = actionCollection()->addAction(QStringLiteral("sessions_manage"));
387
a->setIcon(QIcon::fromTheme(QStringLiteral("view-choose")));
388
a->setText(i18n("&Manage Sessions..."));
389
// Qt::QueuedConnection to avoid deletion of code that is executed when reducing the amount of mainwindows. (bug #227008)
390
connect(a, SIGNAL(triggered()), KateApp::self()->sessionManager(), SLOT(sessionManage()), Qt::QueuedConnection);
392
// quick open menu ;)
393
a = new KateSessionsAction(i18n("&Quick Open Session"), this);
394
actionCollection()->addAction(QStringLiteral("sessions_list"), a);
397
void KateMainWindow::slotDocumentCloseAll()
399
if (KateApp::self()->documentManager()->documentList().size() >= 1 && KMessageBox::warningContinueCancel(this,
400
i18n("This will close all open documents. Are you sure you want to continue?"),
401
i18n("Close all documents"),
402
KStandardGuiItem::cont(),
403
KStandardGuiItem::cancel(),
404
QStringLiteral("closeAll")) != KMessageBox::Cancel) {
405
if (queryClose_internal()) {
406
KateApp::self()->documentManager()->closeAllDocuments(false);
411
void KateMainWindow::slotDocumentCloseOther(KTextEditor::Document *document)
413
if (queryClose_internal(document)) {
414
KateApp::self()->documentManager()->closeOtherDocuments(document);
418
void KateMainWindow::slotDocumentCloseSelected(const QList<KTextEditor::Document *> &docList)
420
QList<KTextEditor::Document *> documents;
421
foreach(KTextEditor::Document * doc, docList) {
422
if (queryClose_internal(doc)) {
423
documents.append(doc);
427
KateApp::self()->documentManager()->closeDocuments(documents);
430
void KateMainWindow::slotDocumentCloseOther()
432
if (queryClose_internal(m_viewManager->activeView()->document())) {
433
KateApp::self()->documentManager()->closeOtherDocuments(m_viewManager->activeView()->document());
437
bool KateMainWindow::queryClose_internal(KTextEditor::Document *doc)
439
int documentCount = KateApp::self()->documentManager()->documentList().size();
441
if (! showModOnDiskPrompt()) {
445
QList<KTextEditor::Document *> modifiedDocuments = KateApp::self()->documentManager()->modifiedDocumentList();
446
modifiedDocuments.removeAll(doc);
447
bool shutdown = (modifiedDocuments.count() == 0);
450
shutdown = KateSaveModifiedDialog::queryClose(this, modifiedDocuments);
453
if (KateApp::self()->documentManager()->documentList().size() > documentCount) {
454
KMessageBox::information(this,
455
i18n("New file opened while trying to close Kate, closing aborted."),
456
i18n("Closing Aborted"));
464
* queryClose(), take care that after the last mainwindow the stuff is closed
466
bool KateMainWindow::queryClose()
468
// session saving, can we close all views ?
469
// just test, not close them actually
470
if (qApp->isSavingSession()) {
471
return queryClose_internal();
474
// normal closing of window
475
// allow to close all windows until the last without restrictions
476
if (KateApp::self()->mainWindowsCount() > 1) {
480
// last one: check if we can close all documents, try run
481
// and save docs if we really close down !
482
if (queryClose_internal()) {
483
KateApp::self()->sessionManager()->saveActiveSession(true);
490
void KateMainWindow::newWindow()
492
KateApp::self()->newMainWindow(KateApp::self()->sessionManager()->activeSession()->config());
495
void KateMainWindow::slotEditToolbars()
497
KConfigGroup cfg(KSharedConfig::openConfig(), "MainWindow");
498
saveMainWindowSettings(cfg);
500
KEditToolBar dlg(factory());
502
connect(&dlg, SIGNAL(newToolBarConfig()), this, SLOT(slotNewToolbarConfig()));
506
void KateMainWindow::slotNewToolbarConfig()
508
applyMainWindowSettings(KConfigGroup(KSharedConfig::openConfig(), "MainWindow"));
511
void KateMainWindow::slotFileQuit()
513
KateApp::self()->shutdownKate(this);
516
void KateMainWindow::slotFileClose()
518
m_viewManager->slotDocumentClose();
521
void KateMainWindow::slotOpenDocument(QUrl url)
523
m_viewManager->openUrl(url,
529
void KateMainWindow::readOptions()
531
KSharedConfig::Ptr config = KSharedConfig::openConfig();
533
const KConfigGroup generalGroup(config, "General");
534
m_modNotification = generalGroup.readEntry("Modified Notification", false);
535
KateApp::self()->documentManager()->setSaveMetaInfos(generalGroup.readEntry("Save Meta Infos", true));
536
KateApp::self()->documentManager()->setDaysMetaInfos(generalGroup.readEntry("Days Meta Infos", 30));
538
m_paShowPath->setChecked(generalGroup.readEntry("Show Full Path in Title", false));
539
m_paShowStatusBar->setChecked(generalGroup.readEntry("Show Status Bar", true));
540
m_paShowMenuBar->setChecked(generalGroup.readEntry("Show Menu Bar", true));
541
m_paShowTabBar->setChecked(generalGroup.readEntry("Show Tab Bar", true));
543
// emit signal to hide/show statusbars
544
toggleShowStatusBar();
548
void KateMainWindow::saveOptions()
550
KSharedConfig::Ptr config = KSharedConfig::openConfig();
552
KConfigGroup generalGroup(config, "General");
554
generalGroup.writeEntry("Save Meta Infos", KateApp::self()->documentManager()->getSaveMetaInfos());
556
generalGroup.writeEntry("Days Meta Infos", KateApp::self()->documentManager()->getDaysMetaInfos());
558
generalGroup.writeEntry("Show Full Path in Title", m_paShowPath->isChecked());
559
generalGroup.writeEntry("Show Status Bar", m_paShowStatusBar->isChecked());
560
generalGroup.writeEntry("Show Menu Bar", m_paShowMenuBar->isChecked());
561
generalGroup.writeEntry("Show Tab Bar", m_paShowTabBar->isChecked());
564
void KateMainWindow::toggleShowMenuBar(bool showMessage)
566
if (m_paShowMenuBar->isChecked()) {
568
removeMenuBarActionFromContextMenu();
571
const QString accel = m_paShowMenuBar->shortcut().toString();
572
KMessageBox::information(this, i18n("This will hide the menu bar completely."
573
" You can show it again by typing %1.", accel),
574
i18n("Hide menu bar"), QLatin1String("HideMenuBarWarning"));
577
addMenuBarActionToContextMenu();
581
void KateMainWindow::addMenuBarActionToContextMenu()
583
if (m_viewManager->activeView()) {
584
m_viewManager->activeView()->contextMenu()->addAction(m_paShowMenuBar);
588
void KateMainWindow::removeMenuBarActionFromContextMenu()
590
if (m_viewManager->activeView()) {
591
m_viewManager->activeView()->contextMenu()->removeAction(m_paShowMenuBar);
595
void KateMainWindow::toggleShowStatusBar()
597
emit statusBarToggled();
600
bool KateMainWindow::showStatusBar()
602
return m_paShowStatusBar->isChecked();
605
void KateMainWindow::toggleShowTabBar()
607
emit tabBarToggled();
610
bool KateMainWindow::showTabBar()
612
return m_paShowTabBar->isChecked();
615
void KateMainWindow::slotWindowActivated()
617
if (m_viewManager->activeView()) {
618
updateCaption(m_viewManager->activeView()->document());
621
// show view manager in any case
622
if (m_mainStackedWidget->currentWidget() != m_viewManager) {
623
m_mainStackedWidget->setCurrentWidget(m_viewManager);
627
centralWidget()->setFocusProxy(m_viewManager->activeView());
630
void KateMainWindow::slotUpdateOpenWith()
632
if (m_viewManager->activeView()) {
633
documentOpenWith->setEnabled(!m_viewManager->activeView()->document()->url().isEmpty());
635
documentOpenWith->setEnabled(false);
639
void KateMainWindow::dragEnterEvent(QDragEnterEvent *event)
641
if (!event->mimeData()) {
644
const bool accept = event->mimeData()->hasUrls() || event->mimeData()->hasText();
645
event->setAccepted(accept);
648
void KateMainWindow::dropEvent(QDropEvent *event)
650
slotDropEvent(event);
653
void KateMainWindow::slotDropEvent(QDropEvent *event)
655
if (event->mimeData() == 0) {
660
// are we dropping files?
663
if (event->mimeData()->hasUrls()) {
664
QList<QUrl> textlist = event->mimeData()->urls();
666
// Try to get the KTextEditor::View that sent this, and activate it, so that the file opens in the
667
// view where it was dropped
668
KTextEditor::View *kVsender = qobject_cast<KTextEditor::View *>(QObject::sender());
670
QWidget *parent = kVsender->parentWidget();
672
KateViewSpace *vs = qobject_cast<KateViewSpace *>(parent->parentWidget());
674
m_viewManager->setActiveSpace(vs);
679
foreach(const QUrl & url, textlist) {
680
// if url has no file component, try and recursively scan dir
681
KFileItem kitem(url);
682
kitem.setDelayedMimeTypes(true);
684
KIO::ListJob *list_job = KIO::listRecursive(url, KIO::DefaultFlags, false);
685
connect(list_job, SIGNAL(entries(KIO::Job*,KIO::UDSEntryList)),
686
this, SLOT(slotListRecursiveEntries(KIO::Job*,KIO::UDSEntryList)));
688
m_viewManager->openUrl(url);
693
// or are we dropping text?
695
else if (event->mimeData()->hasText()) {
696
KTextEditor::Document *doc =
697
KateApp::self()->documentManager()->createDoc();
698
doc->setText(event->mimeData()->text());
699
m_viewManager->activateView(doc);
703
void KateMainWindow::slotListRecursiveEntries(KIO::Job *job, const KIO::UDSEntryList &list)
705
const QUrl dir = static_cast<KIO::SimpleJob *>(job)->url();
706
foreach(const KIO::UDSEntry & entry, list) {
707
QUrl currentUrl = dir.resolved(QUrl(entry.stringValue(KIO::UDSEntry::UDS_NAME)));
709
if (!entry.isDir()) {
710
m_viewManager->openUrl(currentUrl);
715
void KateMainWindow::editKeys()
717
KShortcutsDialog dlg(KShortcutsEditor::AllActions, KShortcutsEditor::LetterShortcutsAllowed, this);
719
QList<KXMLGUIClient *> clients = guiFactory()->clients();
721
foreach(KXMLGUIClient * client, clients) {
722
// FIXME there appear to be invalid clients after session switching
723
// qCDebug(LOG_KATE)<<"adding client to shortcut editor";
724
// qCDebug(LOG_KATE)<<client;
725
// qCDebug(LOG_KATE)<<client->actionCollection();
726
// qCDebug(LOG_KATE)<<client->componentData().aboutData();
727
// qCDebug(LOG_KATE)<<client->componentData().aboutData()->programName();
728
dlg.addCollection(client->actionCollection(), client->componentName());
732
QList<KTextEditor::Document *> l = KateApp::self()->documentManager()->documentList();
733
for (int i = 0; i < l.count(); i++) {
734
// qCDebug(LOG_KATE)<<"reloading Keysettings for document "<<i;
735
l.at(i)->reloadXML();
736
QList<KTextEditor::View *> l1 = l.at(i)->views();
737
for (int i1 = 0; i1 < l1.count(); i1++) {
738
l1.at(i1)->reloadXML();
739
// qCDebug(LOG_KATE)<<"reloading Keysettings for view "<<i<<"/"<<i1;
744
void KateMainWindow::openUrl(const QString &name)
746
m_viewManager->openUrl(QUrl(name));
749
void KateMainWindow::slotConfigure()
751
showPluginConfigPage(0, 0);
754
void KateMainWindow::showPluginConfigPage(KTextEditor::Plugin *configpageinterface, uint id)
756
if (!m_viewManager->activeView()) {
760
KateConfigDialog *dlg = new KateConfigDialog(this, m_viewManager->activeView());
761
if (configpageinterface) {
762
dlg->showAppPluginPage(configpageinterface, id);
765
if (dlg->exec() == QDialog::Accepted) {
766
m_fileOpenRecent->setMaxItems(KateConfigDialog::recentFilesMaxCount());
771
m_viewManager->reactivateActiveView(); // gui (toolbars...) needs to be updated, because
772
// of possible changes that the configure dialog
773
// could have done on it, specially for plugins.
776
QUrl KateMainWindow::activeDocumentUrl()
778
// anders: i make this one safe, as it may be called during
779
// startup (by the file selector)
780
KTextEditor::View *v = m_viewManager->activeView();
782
return v->document()->url();
787
void KateMainWindow::mSlotFixOpenWithMenu()
789
// dh: in bug #307699, this slot is called when launching the Kate application
790
// unfortunately, noone ever could reproduce except users.
791
KTextEditor::View *activeView = m_viewManager->activeView();
797
QMenu *menu = documentOpenWith->menu();
800
// get a list of appropriate services.
802
QMimeType mime = db.mimeTypeForName(activeView->document()->mimeType());
803
//qCDebug(LOG_KATE) << "mime type: " << mime.name();
806
KService::List offers = KMimeTypeTrader::self()->query(mime.name(), QStringLiteral("Application"));
807
// add all default open-with-actions except "Kate"
808
for (KService::List::Iterator it = offers.begin(); it != offers.end(); ++it) {
809
KService::Ptr service = *it;
810
if (service->name() == QStringLiteral("Kate")) {
813
a = menu->addAction(QIcon::fromTheme(service->icon()), service->name());
814
a->setData(service->entryPath());
816
// append "Other..." to call the KDE "open with" dialog.
817
a = documentOpenWith->menu()->addAction(i18n("&Other..."));
818
a->setData(QString());
821
void KateMainWindow::slotOpenWithMenuAction(QAction *a)
824
list.append(m_viewManager->activeView()->document()->url());
826
const QString openWith = a->data().toString();
827
if (openWith.isEmpty()) {
828
// display "open with" dialog
829
KOpenWithDialog dlg(list);
831
KRun::run(*dlg.service(), list, this);
836
KService::Ptr app = KService::serviceByDesktopPath(openWith);
838
KRun::run(*app, list, this);
840
KMessageBox::error(this, i18n("Application '%1' not found.", openWith), i18n("Application not found"));
844
void KateMainWindow::pluginHelp()
846
KHelpClient::invokeHelp(QString(), QStringLiteral("kate-plugins"));
849
void KateMainWindow::aboutEditor()
851
KAboutApplicationDialog ad(KTextEditor::Editor::instance()->aboutData(), this);
855
void KateMainWindow::slotFullScreen(bool t)
857
KToggleFullScreenAction::setFullScreen(this, t);
858
QMenuBar *mb = menuBar();
861
QToolButton *b = new QToolButton(mb);
862
b->setDefaultAction(m_showFullScreenAction);
863
b->setSizePolicy(QSizePolicy(QSizePolicy::Minimum,QSizePolicy::Ignored));
864
b->setFont(QFontDatabase::systemFont(QFontDatabase::SmallestReadableFont));
865
mb->setCornerWidget(b,Qt::TopRightCorner);
867
b->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
869
QWidget *w=mb->cornerWidget(Qt::TopRightCorner);
870
if (w) w->deleteLater();
875
bool KateMainWindow::showModOnDiskPrompt()
877
KTextEditor::Document *doc;
880
list.reserve(KateApp::self()->documentManager()->documentList().size());
881
foreach(doc, KateApp::self()->documentManager()->documentList()) {
882
if (KateApp::self()->documentManager()->documentInfo(doc)->modifiedOnDisc) {
887
if (!list.isEmpty() && !m_modignore) {
888
KateMwModOnHdDialog mhdlg(list, this);
890
bool res = mhdlg.exec();
898
void KateMainWindow::slotDocumentCreated(KTextEditor::Document *doc)
900
connect(doc, SIGNAL(modifiedChanged(KTextEditor::Document*)), this, SLOT(updateCaption(KTextEditor::Document*)));
901
connect(doc, SIGNAL(readWriteChanged(KTextEditor::Document*)), this, SLOT(updateCaption(KTextEditor::Document*)));
902
connect(doc, SIGNAL(documentNameChanged(KTextEditor::Document*)), this, SLOT(updateCaption(KTextEditor::Document*)));
903
connect(doc, SIGNAL(documentUrlChanged(KTextEditor::Document*)), this, SLOT(updateCaption(KTextEditor::Document*)));
904
connect(doc, SIGNAL(documentNameChanged(KTextEditor::Document*)), this, SLOT(slotUpdateOpenWith()));
909
void KateMainWindow::updateCaption()
911
if (m_viewManager->activeView()) {
912
updateCaption(m_viewManager->activeView()->document());
916
void KateMainWindow::updateCaption(KTextEditor::Document *doc)
918
if (!m_viewManager->activeView()) {
919
setCaption(QString(), false);
923
// block signals from inactive docs
924
if (!((KTextEditor::Document *)m_viewManager->activeView()->document() == doc)) {
929
if (m_viewManager->activeView()->document()->url().isEmpty() || (!m_paShowPath || !m_paShowPath->isChecked())) {
930
c = ((KTextEditor::Document *)m_viewManager->activeView()->document())->documentName();
932
c = m_viewManager->activeView()->document()->url().toString();
935
QString sessName = KateApp::self()->sessionManager()->activeSession()->name();
936
if (!sessName.isEmpty()) {
937
sessName = QString::fromLatin1("%1: ").arg(sessName);
940
QString readOnlyCaption;
941
if (!m_viewManager->activeView()->document()->isReadWrite()) {
942
readOnlyCaption = i18n(" [read only]");
945
setCaption(sessName + c + readOnlyCaption + QStringLiteral(" [*]"),
946
m_viewManager->activeView()->document()->isModified());
949
void KateMainWindow::saveProperties(KConfigGroup &config)
953
// store all plugin view states
954
int id = KateApp::self()->mainWindowID(this);
955
foreach(const KatePluginInfo & item, KateApp::self()->pluginManager()->pluginList()) {
956
if (item.plugin && pluginViews().contains(item.plugin)) {
957
if (auto interface = qobject_cast<KTextEditor::SessionConfigInterface *> (pluginViews().value(item.plugin))) {
958
KConfigGroup group(config.config(), QString::fromLatin1("Plugin:%1:MainWindow:%2").arg(item.saveName()).arg(id));
959
interface->writeSessionConfig(group);
964
m_fileOpenRecent->saveEntries(KConfigGroup(config.config(), "Recent Files"));
965
m_viewManager->saveViewConfiguration(config);
968
void KateMainWindow::readProperties(const KConfigGroup &config)
970
// KDE5: TODO startRestore should take a const KConfigBase*, or even just a const KConfigGroup&,
971
// but this propagates down to interfaces/kate/plugin.h so all plugins have to be ported
972
KConfigBase *configBase = const_cast<KConfig *>(config.config());
973
startRestore(configBase, config.name());
975
// perhaps enable plugin guis
976
KateApp::self()->pluginManager()->enableAllPluginsGUI(this, configBase);
980
m_fileOpenRecent->loadEntries(KConfigGroup(config.config(), "Recent Files"));
981
m_viewManager->restoreViewConfiguration(config);
984
void KateMainWindow::saveGlobalProperties(KConfig *sessionConfig)
986
KateApp::self()->documentManager()->saveDocumentList(sessionConfig);
988
KConfigGroup cg(sessionConfig, "General");
989
cg.writeEntry("Last Session", KateApp::self()->sessionManager()->activeSession()->name());
991
// save plugin config !!
992
KateApp::self()->pluginManager()->writeConfig(sessionConfig);
996
void KateMainWindow::saveWindowConfig(const KConfigGroup &_config)
998
KConfigGroup config(_config);
999
saveMainWindowSettings(config);
1000
KWindowConfig::saveWindowSize(windowHandle(), config);
1001
config.writeEntry("WindowState", int(((KParts::MainWindow *)this)->windowState()));
1005
void KateMainWindow::restoreWindowConfig(const KConfigGroup &config)
1007
setWindowState(Qt::WindowNoState);
1008
applyMainWindowSettings(config);
1009
KWindowConfig::restoreWindowSize(windowHandle(), config);
1010
setWindowState(QFlags<Qt::WindowState>(config.readEntry("WindowState", int(Qt::WindowActive))));
1013
void KateMainWindow::slotUpdateBottomViewBar()
1015
//qCDebug(LOG_KATE)<<"slotUpdateHorizontalViewBar()"<<endl;
1016
KTextEditor::View *view = m_viewManager->activeView();
1017
BarState bs = m_bottomViewBarMapping[view];
1018
if (bs.bar() && bs.state()) {
1019
m_bottomContainerStack->setCurrentWidget(bs.bar());
1020
m_bottomContainerStack->currentWidget()->show();
1021
m_bottomViewBarContainer->show();
1023
QWidget *wid = m_bottomContainerStack->currentWidget();
1027
//qCDebug(LOG_KATE)<<wid<<"hiding container"<<endl;
1028
m_bottomViewBarContainer->hide();
1032
void KateMainWindow::queueModifiedOnDisc(KTextEditor::Document *doc)
1034
if (!m_modNotification) {
1038
if (s_modOnHdDialog == 0) {
1042
s_modOnHdDialog = new KateMwModOnHdDialog(list, this);
1044
KWindowSystem::setOnAllDesktops(s_modOnHdDialog->winId(), true);
1045
s_modOnHdDialog->exec();
1046
delete s_modOnHdDialog; // s_modOnHdDialog is set to 0 in destructor of KateMwModOnHdDialog (jowenn!!!)
1047
m_modignore = false;
1049
s_modOnHdDialog->addDocument(doc);
1053
bool KateMainWindow::event(QEvent *e)
1055
if (e->type() == QEvent::ShortcutOverride) {
1056
QKeyEvent *k = static_cast<QKeyEvent *>(e);
1057
emit unhandledShortcutOverride(k);
1059
return KateMDI::MainWindow::event(e);
1062
QObject *KateMainWindow::pluginView(const QString &name)
1064
KTextEditor::Plugin *plugin = KateApp::self()->pluginManager()->plugin(name);
1069
return m_pluginViews.contains(plugin) ? m_pluginViews.value(plugin) : 0;
1072
void KateMainWindow::slotFocusPrevTab()
1074
if (m_viewManager->activeViewSpace()) {
1075
m_viewManager->activeViewSpace()->focusPrevTab();
1079
void KateMainWindow::slotFocusNextTab()
1081
if (m_viewManager->activeViewSpace()) {
1082
m_viewManager->activeViewSpace()->focusNextTab();
1086
void KateMainWindow::slotQuickOpen()
1089
* show quick open and pass focus to it
1091
m_quickOpen->update();
1092
m_mainStackedWidget->setCurrentWidget(m_quickOpen);
1093
centralWidget()->setFocusProxy(m_quickOpen);
1094
m_quickOpen->setFocus();
1097
QWidget *KateMainWindow::createToolView(KTextEditor::Plugin *plugin, const QString &identifier, KTextEditor::MainWindow::ToolViewPosition pos, const QIcon &icon, const QString &text)
1100
return KateMDI::MainWindow::createToolView(plugin, identifier, (KMultiTabBar::KMultiTabBarPosition)(pos), icon.pixmap(QSize(16, 16)), text);
1103
bool KateMainWindow::moveToolView(QWidget *widget, KTextEditor::MainWindow::ToolViewPosition pos)
1105
if (!qobject_cast<KateMDI::ToolView *>(widget)) {
1110
return KateMDI::MainWindow::moveToolView(qobject_cast<KateMDI::ToolView *>(widget), (KMultiTabBar::KMultiTabBarPosition)(pos));
1113
bool KateMainWindow::showToolView(QWidget *widget)
1115
if (!qobject_cast<KateMDI::ToolView *>(widget)) {
1119
return KateMDI::MainWindow::showToolView(qobject_cast<KateMDI::ToolView *>(widget));
1122
bool KateMainWindow::hideToolView(QWidget *widget)
1124
if (!qobject_cast<KateMDI::ToolView *>(widget)) {
1128
return KateMDI::MainWindow::hideToolView(qobject_cast<KateMDI::ToolView *>(widget));