File indexing completed on 2024-05-26 16:11:33

0001 /*
0002  *  Copyright (c) 2009 Cyrille Berger <cberger@cberger.net>
0003  *
0004  * This library is free software; you can redistribute it and/or
0005  * modify it under the terms of the GNU Lesser General Public
0006  * License as published by the Free Software Foundation;
0007  * either version 2, or (at your option) any later version of the License.
0008  *
0009  * This library is distributed in the hope that it will be useful,
0010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0012  * Lesser General Public License for more details.
0013  *
0014  * You should have received a copy of the GNU Lesser General Public License
0015  * along with this library; see the file COPYING.  If not, write to
0016  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0017  * Boston, MA 02110-1301, USA.
0018  */
0019 
0020 #include "MainWindow.h"
0021 
0022 #include <QApplication>
0023 #include <QDesktopWidget>
0024 #include <QDockWidget>
0025 #include <QLayout>
0026 #include <QTabBar>
0027 #include <QDebug>
0028 #include <QFontDatabase>
0029 
0030 #include <kactioncollection.h>
0031 #include <kactionmenu.h>
0032 #include <kconfiggroup.h>
0033 #include <kstandardaction.h>
0034 #include <ksharedconfig.h>
0035 #include <klocalizedstring.h>
0036 
0037 #include <KoDockRegistry.h>
0038 #include <KoDockFactoryBase.h>
0039 #include <KoCanvasObserverBase.h>
0040 
0041 #include "RootSection.h"
0042 #include "View.h"
0043 #include "Canvas.h"
0044 #include "import/DockerManager.h"
0045 #include <kxmlguifactory.h>
0046 
0047 #include "StatusBarItem.h"
0048 
0049 MainWindow::MainWindow(RootSection* document) : m_doc(document), m_activeView(0), m_dockerManager(0)
0050 {
0051     // then, setup our actions
0052     setupActions();
0053 
0054     // Create the docker manager after setting up the action
0055     m_dockerManager = new DockerManager(this);
0056 
0057     // Setup the view
0058     view = new View(m_doc, this);
0059     setCentralWidget(view);
0060 
0061     // a call to KXmlGuiWindow::setupGUI() populates the GUI
0062     // with actions, using KXMLGUI.
0063     // It also applies the saved mainwindow settings, if any, and ask the
0064     // mainwindow to automatically save settings if changed: window size,
0065     // toolbar position, icon size, etc.
0066     setupGUI();
0067 
0068     activateView(view);
0069 
0070     setAutoSaveSettings(qApp->applicationName());
0071 
0072     const int scnum = QApplication::desktop()->screenNumber(parentWidget());
0073     QRect desk = QApplication::desktop()->screenGeometry(scnum);
0074 
0075     // if the desktop is virtual then use virtual screen size
0076     if(QApplication::desktop()->isVirtualDesktop())
0077         desk = QApplication::desktop()->screenGeometry(QApplication::desktop()->screen());
0078 
0079     KConfigGroup config(KSharedConfig::openConfig(), qApp->applicationName());
0080     const QSize size(config.readEntry(QString::fromLatin1("Width %1").arg(desk.width()), 0),
0081                          config.readEntry(QString::fromLatin1("Height %1").arg(desk.height()), 0));
0082     resize(size);
0083 
0084     foreach(QDockWidget * wdg, m_dockWidgets) {
0085         if((wdg->features() & QDockWidget::DockWidgetClosable) == 0) {
0086             wdg->setVisible(true);
0087         }
0088     }
0089 
0090     forceDockTabFonts();
0091 }
0092 
0093 MainWindow::~MainWindow()
0094 {
0095     // The view need to be deleted before the dockermanager
0096     delete view;
0097 }
0098 
0099 void MainWindow::closeEvent(QCloseEvent *e)
0100 {
0101     Q_UNUSED(e);
0102     const int scnum = QApplication::desktop()->screenNumber(parentWidget());
0103     QRect desk = QApplication::desktop()->screenGeometry(scnum);
0104 
0105     if(QApplication::desktop()->isVirtualDesktop()) {
0106         desk = QApplication::desktop()->screenGeometry(QApplication::desktop()->screen());
0107     }
0108 
0109     KConfigGroup config(KSharedConfig::openConfig(), qApp->applicationName());
0110     config.writeEntry(QString::fromLatin1("Width %1").arg(desk.width()), width());
0111     config.writeEntry(QString::fromLatin1("Height %1").arg(desk.height()), height());
0112 }
0113 
0114 void MainWindow::setupActions()
0115 {
0116     KStandardAction::quit(qApp, SLOT(closeAllWindows()), actionCollection());
0117     m_doc->createActions(actionCollection());
0118     m_dockWidgetMenu  = new KActionMenu(i18n("Dockers"), this);
0119     actionCollection()->addAction("settings_dockers_menu", m_dockWidgetMenu);
0120     m_dockWidgetMenu->setVisible(false);
0121 }
0122 
0123 QDockWidget* MainWindow::createDockWidget(KoDockFactoryBase* factory)
0124 {
0125     QDockWidget* dockWidget = 0;
0126 
0127     if(!m_dockWidgetMap.contains(factory->id())) {
0128         dockWidget = factory->createDockWidget();
0129 
0130         // It is quite possible that a dock factory cannot create the dock; don't
0131         // do anything in that case.
0132         if(!dockWidget) return 0;
0133         m_dockWidgets.push_back(dockWidget);
0134 
0135         dockWidget->setObjectName(factory->id());
0136         dockWidget->setParent(this);
0137 
0138         if(dockWidget->widget() && dockWidget->widget()->layout())
0139             dockWidget->widget()->layout()->setContentsMargins(1, 1, 1, 1);
0140 
0141         Qt::DockWidgetArea side = Qt::RightDockWidgetArea;
0142         bool visible = true;
0143 
0144         switch(factory->defaultDockPosition()) {
0145         case KoDockFactoryBase::DockTornOff:
0146             dockWidget->setFloating(true); // position nicely?
0147             break;
0148         case KoDockFactoryBase::DockTop:
0149             side = Qt::TopDockWidgetArea; break;
0150         case KoDockFactoryBase::DockLeft:
0151             side = Qt::LeftDockWidgetArea; break;
0152         case KoDockFactoryBase::DockBottom:
0153             side = Qt::BottomDockWidgetArea; break;
0154         case KoDockFactoryBase::DockRight:
0155             side = Qt::RightDockWidgetArea; break;
0156         case KoDockFactoryBase::DockMinimized:
0157             visible = false; break;
0158         default:;
0159         }
0160 
0161         addDockWidget(side, dockWidget);
0162         if(dockWidget->features() & QDockWidget::DockWidgetClosable) {
0163             m_dockWidgetMenu->addAction(dockWidget->toggleViewAction());
0164             if(!visible)
0165                 dockWidget->hide();
0166         }
0167 
0168         m_dockWidgetMap.insert(factory->id(), dockWidget);
0169     } else {
0170         dockWidget = m_dockWidgetMap[ factory->id()];
0171     }
0172 
0173     connect(dockWidget, SIGNAL(dockLocationChanged(Qt::DockWidgetArea)), this, SLOT(forceDockTabFonts()));
0174 
0175     return dockWidget;
0176 }
0177 
0178 void MainWindow::forceDockTabFonts()
0179 {
0180     QObjectList chis = children();
0181     for(int i = 0; i < chis.size(); ++i) {
0182         if(chis.at(i)->inherits("QTabBar")) {
0183             ((QTabBar *)chis.at(i))->setFont(KoDockRegistry::dockFont());
0184         }
0185     }
0186 }
0187 
0188 DockerManager* MainWindow::dockerManager()
0189 {
0190     return m_dockerManager;
0191 }
0192 
0193 void MainWindow::activateView(View* view)
0194 {
0195     Q_ASSERT(factory());
0196     // Desactivate previous view
0197     if(m_activeView) {
0198         factory()->removeClient(m_activeView);
0199         foreach(StatusBarItem * item, m_statusBarItems[m_activeView]) {
0200             item->ensureItemHidden(statusBar());
0201         }
0202     }
0203 
0204     // Set the new view
0205     m_activeView = view;
0206     if(m_activeView) {
0207         factory()->addClient(view);
0208         // Show the status widget for the current view
0209         foreach(StatusBarItem * item, m_statusBarItems[m_activeView]) {
0210             item->ensureItemShown(statusBar());
0211         }
0212     }
0213 }
0214 
0215 void MainWindow::addStatusBarItem(QWidget* _widget, int _stretch, View* _view)
0216 {
0217     Q_ASSERT(_widget);
0218     Q_ASSERT(_view);
0219     QList<StatusBarItem*>& list = m_statusBarItems[_view];
0220     StatusBarItem* item = new StatusBarItem(_widget, _stretch, _view);
0221     if(_view == m_activeView) {
0222         item->ensureItemShown(statusBar());
0223     }
0224     list.append(item);
0225 }
0226 
0227 void MainWindow::removeStatusBarItem(QWidget* _widget)
0228 {
0229     foreach(View * key, m_statusBarItems.keys()) {
0230         QList<StatusBarItem*>& list = m_statusBarItems[key];
0231         foreach(StatusBarItem * item, list) {
0232             if(item->m_widget == _widget) {
0233                 list.removeAll(item);
0234                 item->ensureItemHidden(statusBar());
0235                 delete item;
0236                 return;
0237             }
0238         }
0239     }
0240     qWarning() << "Widget " << _widget << " not found in the status bar";
0241 }
0242 
0243 QList<KoCanvasObserverBase*> MainWindow::canvasObservers() const
0244 {
0245     QList<KoCanvasObserverBase*> observers;
0246 
0247     foreach(QDockWidget * docker, m_dockWidgets) {
0248         KoCanvasObserverBase *observer = dynamic_cast<KoCanvasObserverBase*>(docker);
0249         if(observer) {
0250             observers << observer;
0251         }
0252     }
0253     return observers;
0254 }