diff options
author | Andrea Diamantini <adjam7@gmail.com> | 2012-08-30 17:31:36 +0200 |
---|---|---|
committer | Andrea Diamantini <adjam7@gmail.com> | 2012-12-10 02:48:05 +0100 |
commit | ab5b4316783e763741db7d66460d616619f23989 (patch) | |
tree | 1e4f7612e5978d44c2fbd9d2d3bb157cf54f44e4 | |
parent | Save & restore window dimension/position (diff) | |
download | rekonq-ab5b4316783e763741db7d66460d616619f23989.tar.xz |
Implement RekonqWindow
Now, all the "KMainWindow" logic is moved to this new class.
"Restored" session management.
NOTE: Probably needs some fixes yet, but seems going in the
right direction...
-rw-r--r-- | src/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/main.cpp | 6 | ||||
-rw-r--r-- | src/tabwindow/rekonqwindow.cpp | 340 | ||||
-rw-r--r-- | src/tabwindow/rekonqwindow.h | 127 | ||||
-rw-r--r-- | src/tabwindow/tabwindow.cpp | 76 | ||||
-rw-r--r-- | src/tabwindow/tabwindow.h | 10 |
6 files changed, 479 insertions, 81 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 682953f8..5c429a7a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -62,6 +62,7 @@ set(rekonq_KDEINIT_SRCS sync/syncgooglesettingswidget.cpp sync/syncoperasettingswidget.cpp #---------------------------------------- + tabwindow/rekonqwindow.cpp tabwindow/tabbar.cpp tabwindow/tabhighlighteffect.cpp tabwindow/tabpreviewpopup.cpp diff --git a/src/main.cpp b/src/main.cpp index 3a37f067..7b468bae 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -91,5 +91,11 @@ extern "C" KDE_EXPORT int kdemain(int argc, char **argv) QCoreApplication::setApplicationName(QLatin1String("rekonq")); QCoreApplication::setApplicationVersion(REKONQ_VERSION); + if (app.isSessionRestored()) + { + for (int i = 1; TabWindow::canBeRestored(i); i++) + app.newTabWindow()->restore(i); + } + return app.exec(); } diff --git a/src/tabwindow/rekonqwindow.cpp b/src/tabwindow/rekonqwindow.cpp new file mode 100644 index 00000000..f3e321bb --- /dev/null +++ b/src/tabwindow/rekonqwindow.cpp @@ -0,0 +1,340 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2012 by Andrea Diamantini <adjam7 at gmail dot com> +* +* +* 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 <http://www.gnu.org/licenses/>. +* +* ============================================================ */ + + +// Self Includes +#include "rekonqwindow.h" +#include "rekonqwindow.moc" + +// KDE Includes +#include <KApplication> +#include <KCmdLineArgs> +#include <KSessionManager> + +// Qt Includes +#include <QCloseEvent> +#include <QDesktopWidget> + + +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<RekonqWindow*>, 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); +} + + +QList<RekonqWindow*> 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); + + QSize defaultSize = desktopRect.size() * 0.8; + + KConfigGroup cg(_cg); + + QString widthString = QString::fromLatin1("Width %1").arg(desktopRect.width()); + int w = cg.readEntry(widthString, defaultSize.width() ); + + QString heightString = QString::fromLatin1("Height %1").arg(desktopRect.height()); + int h = cg.readEntry(heightString, defaultSize.height() ); + + resize(w, h); + + 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 + if (!restoreGeometry( QByteArray::fromBase64(geometry) )) + move( (desktopRect.width()-width())/2, (desktopRect.height()-height())/2 ); +} + + +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) +{ + saveAutoSaveSettings(); + KTabWidget::resizeEvent(event); +} + + +void RekonqWindow::saveAutoSaveSettings() +{ + kDebug() << "CIAOLA CIAOLA"; + + 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; +} diff --git a/src/tabwindow/rekonqwindow.h b/src/tabwindow/rekonqwindow.h new file mode 100644 index 00000000..b3f2f698 --- /dev/null +++ b/src/tabwindow/rekonqwindow.h @@ -0,0 +1,127 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2012 by Andrea Diamantini <adjam7 at gmail dot com> +* +* +* 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 <http://www.gnu.org/licenses/>. +* +* ============================================================ */ + + + +#ifndef REKONQ_WINDOW_H +#define REKONQ_WINDOW_H + + +// Rekonq Includes +#include "rekonq_defines.h" + +// KDE Includes +#include <KTabWidget> +#include <KConfig> +#include <KConfigGroup> + +// Qt Includes +#include <QTimer> + +/** + * This is rekonq (re)implementation of KMainWindow, + * given that we'd like to NOT use a "real" xMainWindow + * but a widget with the nice mainwindow properties + * (eg: session management, auto save dimension, etc) but + * NOT its peculiar containers (eg: toolbars, menubar, statusbar, + * central widget...) + * + */ +class RekonqWindow : public KTabWidget +{ + friend class KRWSessionManager; + + Q_OBJECT + +public: + explicit RekonqWindow( QWidget* parent = 0 ); + + virtual ~RekonqWindow(); + + /** + * List of members of RekonqWindow class. + */ + static QList<RekonqWindow*> windowList(); + + /** + * If the session did contain so high a @p number, @p true is returned, + * else @p false. + * @see restore() + **/ + static bool canBeRestored( int number ); + + /** + * Try to restore the toplevel widget as defined by @p number (1..X). + * + * You should call canBeRestored() first. + * + **/ + bool restore( int number, bool show = true ); + +protected: + /** + * Save your instance-specific properties. The function is + * invoked when the session manager requests your application + * to save its state. + * + * Please reimplement these function in childclasses. + * + * Note: No user interaction is allowed + * in this function! + * + */ + virtual void saveProperties( KConfigGroup & ) {} + + /** + * Read your instance-specific properties. + * + * Is called indirectly by restore(). + */ + virtual void readProperties( const KConfigGroup & ) {} + + void savePropertiesInternal( KConfig*, int ); + bool readPropertiesInternal( KConfig*, int ); + + /** + * For inherited classes + */ + void saveWindowSize( const KConfigGroup &config ) const; + /** + * For inherited classes + * Note that a -geometry on the command line has priority. + */ + void restoreWindowSize( const KConfigGroup & config ); + + /// parse the geometry from the geometry command line argument + void parseGeometry(); + + virtual void resizeEvent(QResizeEvent *); + +private Q_SLOTS: + void saveAutoSaveSettings(); + +}; + +#endif // REKONQ_WINDOW_H diff --git a/src/tabwindow/tabwindow.cpp b/src/tabwindow/tabwindow.cpp index efc3a61a..4d4cdab3 100644 --- a/src/tabwindow/tabwindow.cpp +++ b/src/tabwindow/tabwindow.cpp @@ -59,17 +59,10 @@ TabWindow::TabWindow(bool withTab, QWidget *parent) - : KTabWidget(parent) + : RekonqWindow(parent) , _addTabButton(new QToolButton(this)) , _openedTabsCounter(0) { - // 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); - setContentsMargins(0, 0, 0, 0); setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); @@ -113,73 +106,6 @@ TabWindow::TabWindow(bool withTab, QWidget *parent) addTab(tab, i18n("new tab")); setCurrentWidget(tab); } - - loadWindowSettings(); -} - - -TabWindow::~TabWindow() -{ - saveWindowSettings(); -} - - -void TabWindow::loadWindowSettings() -{ - KSharedConfig::Ptr config = KGlobal::config(); - KConfigGroup cg = KConfigGroup(config.data(), QL1S("TabWindow")); - - int scnum = QApplication::desktop()->screenNumber(window()); - QRect desktopRect = QApplication::desktop()->screenGeometry(scnum); - - QSize defaultSize = desktopRect.size() * 0.8; - - QString widthString = QString::fromLatin1("Width %1").arg(desktopRect.width()); - int w = cg.readEntry(widthString, defaultSize.width() ); - - QString heightString = QString::fromLatin1("Height %1").arg(desktopRect.height()); - int h = cg.readEntry(heightString, defaultSize.height() ); - - resize(w, h); - - 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 - if (!restoreGeometry( QByteArray::fromBase64(geometry) )) - move( (desktopRect.width()-width())/2, (desktopRect.height()-height())/2 ); -} - - -void TabWindow::saveWindowSettings() -{ - KSharedConfig::Ptr config = KGlobal::config(); - KConfigGroup cg = KConfigGroup(config.data(), QL1S("TabWindow")); - - 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(); - } - - 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() ); } diff --git a/src/tabwindow/tabwindow.h b/src/tabwindow/tabwindow.h index c4ba70be..9dda54c3 100644 --- a/src/tabwindow/tabwindow.h +++ b/src/tabwindow/tabwindow.h @@ -31,6 +31,9 @@ // Rekonq Includes #include "rekonq_defines.h" +// Local Includes +#include "rekonqwindow.h" + // KDE Includes #include <KTabWidget> @@ -51,13 +54,12 @@ class WebWindow; // -------------------------------------------------------------------------------------- -class TabWindow : public KTabWidget +class TabWindow : public RekonqWindow { Q_OBJECT public: TabWindow(bool withTab = true, QWidget *parent = 0); - virtual ~TabWindow(); WebWindow* currentWebWindow() const; WebWindow* webWindow(int index) const; @@ -74,10 +76,6 @@ private: */ WebWindow *prepareNewTab(WebPage *page = 0); - // internal - void loadWindowSettings(); - void saveWindowSettings(); - private Q_SLOTS: /** * Updates new tab button position |