/* ============================================================ * * This file is a part of the rekonq project * * Copyright (C) 2012 by Andrea Diamantini * * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License or (at your option) version 3 or any later version * accepted by the membership of KDE e.V. (or its successor approved * by the membership of KDE e.V.), which shall act as a proxy * defined in Section 14 of version 3 of the license. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * ============================================================ */ // Self Includes #include "rekonqwindow.h" #include "rekonqwindow.moc" // KDE Includes #include #include #include // Qt Includes #include #include static bool s_no_query_exit = false; class KRWSessionManager : public KSessionManager { public: KRWSessionManager() { } ~KRWSessionManager() { } bool dummyInit() { return true; } bool saveState(QSessionManager&) { KConfig* config = KApplication::kApplication()->sessionConfig(); int n = 0; Q_FOREACH(RekonqWindow * rw, RekonqWindow::windowList()) { n++; rw->savePropertiesInternal(config, n); } KConfigGroup group(config, "Number"); group.writeEntry("NumberOfWindows", n); return true; } bool commitData(QSessionManager& sm) { // not really a fast method but the only compatible one if (sm.allowsInteraction()) { bool canceled = false; ::s_no_query_exit = true; Q_FOREACH(RekonqWindow * window, RekonqWindow::windowList()) { if (!window->testAttribute(Qt::WA_WState_Hidden)) { QCloseEvent e; QApplication::sendEvent(window, &e); canceled = !e.isAccepted(); if (canceled) break; } } ::s_no_query_exit = false; if (canceled) return false; return true; } // the user wants it, the user gets it return true; } }; K_GLOBAL_STATIC(KRWSessionManager, ktwsm) K_GLOBAL_STATIC(QList, sWindowList) // ---------------------------------------------------------------------------------------------------- RekonqWindow::RekonqWindow(QWidget* parent) : KTabWidget(parent) { // This has to be a window... setWindowFlags(Qt::Window); // Setting attributes (just to be sure...) setAttribute(Qt::WA_DeleteOnClose, true); setAttribute(Qt::WA_QuitOnClose, true); ktwsm->dummyInit(); sWindowList->append(this); QString geometry; KCmdLineArgs *args = KCmdLineArgs::parsedArgs("kde"); if (args && args->isSet("geometry")) geometry = args->getOption("geometry"); if (geometry.isNull()) // if there is no geometry, it doesn't matter { KSharedConfig::Ptr cf = KGlobal::config(); KConfigGroup cg(cf, QL1S("TabWindow")); restoreWindowSize(cg); } else { parseGeometry(); } setWindowTitle(KGlobal::caption()); } RekonqWindow::~RekonqWindow() { sWindowList->removeAll(this); KSharedConfig::Ptr cf = KGlobal::config(); KConfigGroup cg(cf, QL1S("TabWindow")); saveWindowSize(cg); } QSize RekonqWindow::sizeHint() const { QRect desktopRect = QApplication::desktop()->screenGeometry(); QSize size = desktopRect.size() * 0.8; return size; } QList RekonqWindow::windowList() { return *sWindowList; } void RekonqWindow::savePropertiesInternal(KConfig *config, int number) { QString s; s.setNum(number); s.prepend(QL1S("WindowProperties")); KConfigGroup cg(config, s); // store objectName, className, Width and Height for later restoring // (Only useful for session management) cg.writeEntry(QL1S("ObjectName"), objectName()); cg.writeEntry(QL1S("ClassName"), metaObject()->className()); saveWindowSize(cg); s.setNum(number); cg = KConfigGroup(config, s); saveProperties(cg); } bool RekonqWindow::readPropertiesInternal(KConfig *config, int number) { // in order they are in toolbar list QString s; s.setNum(number); s.prepend(QL1S("WindowProperties")); KConfigGroup cg(config, s); // restore the object name (window role) if (cg.hasKey(QL1S("ObjectName"))) setObjectName(cg.readEntry("ObjectName").toLatin1()); // latin1 is right here restoreWindowSize(cg); s.setNum(number); KConfigGroup grp(config, s); readProperties(grp); return true; } void RekonqWindow::restoreWindowSize(const KConfigGroup & _cg) { int scnum = QApplication::desktop()->screenNumber(window()); QRect desktopRect = QApplication::desktop()->screenGeometry(scnum); KConfigGroup cg(_cg); QString geometryKey = QString::fromLatin1("geometry-%1-%2").arg(desktopRect.width()).arg(desktopRect.height()); QByteArray geometry = cg.readEntry(geometryKey, QByteArray()); // if first time run, center window: resize && move.. if (!restoreGeometry(QByteArray::fromBase64(geometry))) { QSize defaultSize = desktopRect.size() * 0.8; resize(defaultSize); move((desktopRect.width() - width()) / 2, (desktopRect.height() - height()) / 2); } checkPosition(); } void RekonqWindow::saveWindowSize(const KConfigGroup & _cg) const { int scnum = QApplication::desktop()->screenNumber(window()); QRect desktopRect = QApplication::desktop()->screenGeometry(scnum); int w, h; if (isMaximized()) { w = desktopRect.width() + 1; h = desktopRect.height() + 1; } else { w = width(); h = height(); } KConfigGroup cg(_cg); QString widthString = QString::fromLatin1("Width %1").arg(desktopRect.width()); cg.writeEntry(widthString, w); QString heightString = QString::fromLatin1("Height %1").arg(desktopRect.height()); cg.writeEntry(heightString, h); // geometry is saved separately for each resolution QString geometryKey = QString::fromLatin1("geometry-%1-%2").arg(desktopRect.width()).arg(desktopRect.height()); QByteArray geometry = saveGeometry(); cg.writeEntry(geometryKey, geometry.toBase64()); } void RekonqWindow::parseGeometry() { QString cmdlineGeometry; KCmdLineArgs *args = KCmdLineArgs::parsedArgs("kde"); if (args->isSet("geometry")) cmdlineGeometry = args->getOption("geometry"); Q_ASSERT(!cmdlineGeometry.isNull()); // #if defined Q_WS_X11 // int x, y; // int w, h; // int m = XParseGeometry( cmdlineGeometry.toLatin1(), &x, &y, (unsigned int*)&w, (unsigned int*)&h); // if (parsewidth) { // const QSize minSize = minimumSize(); // const QSize maxSize = maximumSize(); // if ( !(m & WidthValue) ) // w = width(); // if ( !(m & HeightValue) ) // h = height(); // w = qMin(w,maxSize.width()); // h = qMin(h,maxSize.height()); // w = qMax(w,minSize.width()); // h = qMax(h,minSize.height()); // resize(w, h); // } else { // if ( (m & XNegative) ) // x = KApplication::desktop()->width() + x - w; // else if ( (m & XValue) ) // x = geometry().x(); // if ( (m & YNegative) ) // y = KApplication::desktop()->height() + y - h; // else if ( (m & YValue) ) // y = geometry().y(); // // move(x, y); // } // #endif } void RekonqWindow::resizeEvent(QResizeEvent *event) { if (!isFullScreen()) saveAutoSaveSettings(); KTabWidget::resizeEvent(event); } void RekonqWindow::saveAutoSaveSettings() { kDebug() << "AUTO SAVING SETTINGS..."; KSharedConfig::Ptr cf = KGlobal::config(); KConfigGroup cg(cf, QL1S("TabWindow")); saveWindowSize(cg); } bool RekonqWindow::canBeRestored(int number) { if (!qApp->isSessionRestored()) return false; KConfig *config = kapp->sessionConfig(); if (!config) return false; KConfigGroup group(config, "Number"); const int n = group.readEntry("NumberOfWindows", 1); return number >= 1 && number <= n; } bool RekonqWindow::restore(int number, bool show) { if (!canBeRestored(number)) return false; KConfig *config = kapp->sessionConfig(); if (readPropertiesInternal(config, number)) { if (show) RekonqWindow::show(); return false; } return false; } // NOTE: For internal purpose only ------------------------------------------------------ int RekonqWindow::addTab(QWidget *page, const QString &label) { setUpdatesEnabled(false); int i = KTabWidget::addTab(page, label); setUpdatesEnabled(true); return i; } int RekonqWindow::addTab(QWidget *page, const QIcon &icon, const QString &label) { setUpdatesEnabled(false); int i = KTabWidget::addTab(page, icon, label); setUpdatesEnabled(true); return i; } int RekonqWindow::insertTab(int index, QWidget *page, const QString &label) { setUpdatesEnabled(false); int i = KTabWidget::insertTab(index, page, label); setUpdatesEnabled(true); return i; } int RekonqWindow::insertTab(int index, QWidget *page, const QIcon &icon, const QString &label) { setUpdatesEnabled(false); int i = KTabWidget::insertTab(index, page, icon, label); setUpdatesEnabled(true); return i; } // -------------------------------------------------------------------------------------- void RekonqWindow::checkPosition() { // no need to check trivial positions... if (isMaximized()) return; QList wList = RekonqWindow::windowList(); int wNumber = wList.count(); // no need to check first window... if (wNumber <= 1) return; int div = wNumber % 4; int scnum = QApplication::desktop()->screenNumber(window()); QRect desktopRect = QApplication::desktop()->screenGeometry(scnum); switch (div) { case 2: // left down move(desktopRect.width() - width(), desktopRect.height() - height()); break; case 3: // right down move(0, desktopRect.height() - height()); break; case 0: // left top move(desktopRect.width() - width(), 0); break; case 1: // right top move(0, 0); break; default: kDebug() << "OOPS...THIS SHOULD NEVER HAPPEN!!"; break; } }