From 16c625403695c82055388fb3b2bda728d33028c1 Mon Sep 17 00:00:00 2001 From: Andrea Diamantini Date: Mon, 23 Jul 2012 17:55:03 +0200 Subject: TabWindow, first import :) --- src/CMakeLists.txt | 61 +++++++ src/tabhistory.h | 63 +++++++ src/tabmain.cpp | 88 +++++++++ src/tabwindow/tabbar.cpp | 242 ++++++++++++++++++++++++ src/tabwindow/tabbar.h | 61 +++++++ src/tabwindow/tabwindow.cpp | 436 ++++++++++++++++++++++++++++++++++++++++++++ src/tabwindow/tabwindow.h | 100 ++++++++++ src/webwindow/webpage.cpp | 60 ++++++ src/webwindow/webpage.h | 54 ++++++ src/webwindow/webwindow.cpp | 150 +++++++++++++++ src/webwindow/webwindow.h | 69 +++++++ 11 files changed, 1384 insertions(+) create mode 100644 src/CMakeLists.txt create mode 100644 src/tabhistory.h create mode 100644 src/tabmain.cpp create mode 100644 src/tabwindow/tabbar.cpp create mode 100644 src/tabwindow/tabbar.h create mode 100644 src/tabwindow/tabwindow.cpp create mode 100644 src/tabwindow/tabwindow.h create mode 100644 src/webwindow/webpage.cpp create mode 100644 src/webwindow/webpage.h create mode 100644 src/webwindow/webwindow.cpp create mode 100644 src/webwindow/webwindow.h (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 00000000..eee8b129 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,61 @@ +### ------- sub dirs ------- + +ADD_SUBDIRECTORY( data ) + + +### ------- SETTING REKONQ FILES.. + +set(rekonq_KDEINIT_SRCS + #---------------------------------------- + tabwindow/tabbar.cpp + tabwindow/tabwindow.cpp + #---------------------------------------- + webwindow/webpage.cpp + webwindow/webwindow.cpp +) + + +### ------------- INCLUDING DIRECTORIES... + +INCLUDE_DIRECTORIES ( ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/tabwindow + ${CMAKE_CURRENT_SOURCE_DIR}/webwindow + ${CMAKE_CURRENT_BINARY_DIR} + ${KDE4_INCLUDES} + ${QT4_INCLUDES} +) + +### -------------- ADDING DEFINITIONS... + +ADD_DEFINITIONS ( ${KDE4_DEFINITIONS} ) + + +### -------------- ADDING APPLICATION ICON... + +KDE4_ADD_APP_ICON( rekonq_KDEINIT_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/../icons/hi*-app-rekonq.png ) + + +### --------------- ADDING EXECUTABLE... + +# NOTE: This is the simple main used to test the tabwindow :) +KDE4_ADD_KDEINIT_EXECUTABLE( rekonq ${rekonq_KDEINIT_SRCS} tabmain.cpp ) + + +### --------------- TARGETTING LINK LIBRARIES... + +TARGET_LINK_LIBRARIES ( kdeinit_rekonq + ${QT_LIBRARIES} + ${QT_QTSCRIPT_LIBRARY} + ${QT_QTWEBKIT_LIBRARY} + ${KDE4_KDEWEBKIT_LIBS} + ${KDE4_KUTILS_LIBS} + ${KDE4_KDEUI_LIBS} + ${KDE4_KIO_LIBS} + ${KDE4_KPARTS_LIBS} +) + + +### ------------ INSTALL FILES... + +INSTALL( TARGETS rekonq ${INSTALL_TARGETS_DEFAULT_ARGS} ) +INSTALL( TARGETS kdeinit_rekonq ${INSTALL_TARGETS_DEFAULT_ARGS} ) diff --git a/src/tabhistory.h b/src/tabhistory.h new file mode 100644 index 00000000..81fd723b --- /dev/null +++ b/src/tabhistory.h @@ -0,0 +1,63 @@ +/*************************************************************************** + * 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) any later version. * + * * + * 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, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + + +#ifndef TAB_HISTORY +#define TAB_HISTORY + + +#include +#include +#include + + +class TabHistory +{ +public: + explicit TabHistory(QWebHistory *h = 0) + { + if (h) + { + title = h->currentItem().title(); + url = h->currentItem().url().toString(); + QDataStream stream(&history, QIODevice::ReadWrite); + stream << *h; + } + } + + inline bool operator ==(const TabHistory &other) const + { + return history == other.history; + } + + void applyHistory(QWebHistory *h) + { + if (h) + { + QDataStream stream(&history, QIODevice::ReadOnly); + stream >> *h; + } + } + + QString title; + QString url; + QByteArray history; +}; + +#endif // TAB_HISTORY diff --git a/src/tabmain.cpp b/src/tabmain.cpp new file mode 100644 index 00000000..7eb229dd --- /dev/null +++ b/src/tabmain.cpp @@ -0,0 +1,88 @@ +/*************************************************************************** + * 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) any later version. * + * * + * 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, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + + +// version include +#include "config-version.h" + +#include "tabwindow.h" + +#include +#include +#include + +#include +#include + + +static const char description[] = + I18N_NOOP("A lightweight Web Browser for KDE based on WebKit"); + + +extern "C" KDE_EXPORT int kdemain(int argc, char **argv) +{ + KAboutData about("rekonq", + 0, + ki18n("rekonq"), + REKONQ_VERSION, + ki18n(description), + KAboutData::License_GPL_V3, + ki18n("(C) 2008-2012 Andrea Diamantini"), + KLocalizedString(), + "http://rekonq.kde.org" + ); + + // Initialize command line args + KCmdLineArgs::init(argc, argv, &about); + + // Define the command line options using KCmdLineOptions + KCmdLineOptions options; + + // adding URL option + options.add("+[URL]" , ki18n("Location to open")); + + // Register the supported options + KCmdLineArgs::addCmdLineOptions(options); + + KApplication app; + + QWebSettings::setIconDatabasePath("/tmp/iconcache"); + + TabWindow *w = new TabWindow; + + // no session.. just start up normally + KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); + if (args->count() == 0) + { + w->newCleanTab(); + w->show(); + } + else + { + int i = 0; + for (; i < args->count(); i++) + { + w->loadUrlInNewTab(QUrl::fromUserInput(args->arg(i))); + w->show(); + } + } + args->clear(); + + return app.exec(); +} diff --git a/src/tabwindow/tabbar.cpp b/src/tabwindow/tabbar.cpp new file mode 100644 index 00000000..06b90897 --- /dev/null +++ b/src/tabwindow/tabbar.cpp @@ -0,0 +1,242 @@ +/*************************************************************************** + * 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) any later version. * + * * + * 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, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + + +#include "tabbar.h" +#include "tabbar.moc" + +#include "tabwindow.h" + +#include +#include +#include +#include +#include + + +TabBar::TabBar(QWidget *parent) + : KTabBar(parent) +{ + setElideMode(Qt::ElideRight); + + setTabsClosable(true); + setMovable(true); + setAcceptDrops(true); + + // avoid ambiguos shortcuts. See BUG:275858 + KAcceleratorManager::setNoAccel(this); + + // context menu(s) + setContextMenuPolicy(Qt::CustomContextMenu); + + connect(this, SIGNAL(contextMenu(int, QPoint)), this, SLOT(contextMenu(int, QPoint))); + connect(this, SIGNAL(emptyAreaContextMenu(QPoint)), this, SLOT(emptyAreaContextMenu(QPoint))); +} + + +QSize TabBar::tabSizeHint(int index) const +{ + Q_UNUSED(index); + + QWidget* p = qobject_cast(parent()); + + int maxTabBarWidth = p->size().width(); + + int baseTabWidth = maxTabBarWidth / genericTabNumber; + + int minTabWidth = p->sizeHint().width() / genericTabNumber; + + int w = baseTabWidth; + if (count() >= genericTabNumber) + { + w = minTabWidth; + } + + int h = size().height(); + + QSize ts = QSize(w, h); + return ts; +} + + +void TabBar::cloneTab() +{ + KAction *a = qobject_cast(sender()); + if (a) + { + int index = a->data().toInt(); + emit cloneTab(index); + } +} + + +void TabBar::closeTab() +{ + KAction *a = qobject_cast(sender()); + if (a) + { + int index = a->data().toInt(); + emit closeTab(index); + } +} + + +void TabBar::closeOtherTabs() +{ + KAction *a = qobject_cast(sender()); + if (a) + { + int index = a->data().toInt(); + emit closeOtherTabs(index); + } +} + + +void TabBar::reloadTab() +{ + KAction *a = qobject_cast(sender()); + if (a) + { + int index = a->data().toInt(); + emit reloadTab(index); + } +} + + +void TabBar::detachTab() +{ + KAction *a = qobject_cast(sender()); + if (a) + { + int index = a->data().toInt(); + emit detachTab(index); + } +} + + +void TabBar::reopenLastClosedTab() +{ + KAction *a = qobject_cast(sender()); + if (a) + { + int index = a->data().toInt(); + emit restoreClosedTab(index); + } +} + + +void TabBar::contextMenu(int tab, const QPoint &pos) +{ + TabWindow *w = qobject_cast(parent()); + + KAction *a; + + KMenu menu; + + a = new KAction(KIcon("tab-new"), i18n("New &Tab"), this); + connect(a, SIGNAL(triggered(bool)), w, SLOT(newCleanTab())); + menu.addAction(a); + + menu.addSeparator(); // ---------------------------------------------------------------- + + a = new KAction(KIcon("tab-duplicate"), i18n("Clone"), this); + a->setData(tab); + connect(a, SIGNAL(triggered(bool)), this, SLOT(cloneTab())); + menu.addAction(a); + + a = new KAction(KIcon("view-refresh"), i18n("Reload"), this); + connect(a, SIGNAL(triggered(bool)), this, SLOT(reloadTab())); + a->setData(tab); + menu.addAction(a); + + if (count() > 1) + { + a = new KAction(KIcon("tab-detach"), i18n("Detach"), this); + connect(a, SIGNAL(triggered(bool)), this, SLOT(detachTab())); + a->setData(tab); + menu.addAction(a); + } + + menu.addSeparator(); // ---------------------------------------------------------------- + + a = new KAction(KIcon("tab-close"), i18n("&Close"), this); + a->setData(tab); + connect(a, SIGNAL(triggered(bool)), this, SLOT(closeTab())); + menu.addAction(a); + + if (count() > 1) + { + a = new KAction(KIcon("tab-close-other"), i18n("Close &Other Tabs"), this); + connect(a, SIGNAL(triggered(bool)), this, SLOT(closeOtherTabs())); + a->setData(tab); + menu.addAction(a); + } + + menu.addSeparator(); + + + a = new KAction(KIcon("tab-new"), i18n("Open Last Closed Tab"), this); + a->setData(0); // last closed tab has index 0! + connect(a, SIGNAL(triggered(bool)), this, SLOT(reopenLastClosedTab())); + menu.addAction(a); + + if (count() > 1) + { + a = new KAction(KIcon("bookmark-new"), i18n("Bookmarks all tabs"), this); + menu.addAction(a); + } + else + { + a = new KAction(KIcon("bookmark-new"), i18n("Bookmark"), this); + menu.addAction(a); + } + + menu.exec(pos); +} + + +void TabBar::emptyAreaContextMenu(const QPoint &pos) +{ + TabWindow *w = qobject_cast(parent()); + + KAction *a; + + KMenu menu; + + a = new KAction(KIcon("tab-new"), i18n("New &Tab"), this); + connect(a, SIGNAL(triggered(bool)), w, SLOT(newCleanTab())); + menu.addAction(a); + + a = new KAction(KIcon("tab-new"), i18n("Open Last Closed Tab"), this); + a->setData(0); // last closed tab has index 0! + menu.addAction(a); + + if (count() > 1) + { + a = new KAction(KIcon("bookmark-new"), i18n("Bookmarks all tabs"), this); + menu.addAction(a); + } + else + { + a = new KAction(KIcon("bookmark-new"), i18n("Bookmark"), this); + menu.addAction(a); + } + + menu.exec(pos); +} diff --git a/src/tabwindow/tabbar.h b/src/tabwindow/tabbar.h new file mode 100644 index 00000000..e3bf6d9a --- /dev/null +++ b/src/tabwindow/tabbar.h @@ -0,0 +1,61 @@ +/*************************************************************************** + * 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) any later version. * + * * + * 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, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + + +#ifndef TAB_BAR +#define TAB_BAR + + +// KDE Includes +#include + + +class TabBar : public KTabBar +{ + Q_OBJECT + +public: + TabBar(QWidget *parent); + + static const int genericTabNumber = 6; + +protected: + virtual QSize tabSizeHint(int index) const; + +Q_SIGNALS: + void cloneTab(int); + void closeTab(int); + void closeOtherTabs(int); + void reloadTab(int); + void detachTab(int); + void restoreClosedTab(int); + +private Q_SLOTS: + void cloneTab(); + void closeTab(); + void closeOtherTabs(); + void reloadTab(); + void detachTab(); + void reopenLastClosedTab(); + + void contextMenu(int, const QPoint &); + void emptyAreaContextMenu(const QPoint &); +}; + +#endif // TAB_BAR diff --git a/src/tabwindow/tabwindow.cpp b/src/tabwindow/tabwindow.cpp new file mode 100644 index 00000000..4a9a8abf --- /dev/null +++ b/src/tabwindow/tabwindow.cpp @@ -0,0 +1,436 @@ +/*************************************************************************** + * 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) any later version. * + * * + * 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, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + + +#include "tabwindow.h" +#include "tabwindow.moc" + +#include "webpage.h" +#include "webwindow.h" +#include "tabbar.h" + +#include "tabhistory.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + + +TabWindow::TabWindow(QWidget *parent) + : KTabWidget(parent) + , _addTabButton(new QToolButton(this)) + , _openedTabsCounter(0) +{ + // This has to be a window... + setWindowFlags(Qt::Window); + + setContentsMargins(0, 0, 0, 0); + + setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); + + // set mouse tracking for tab previews + setMouseTracking(true); + + // setting tabbar + TabBar *tabBar = new TabBar(this); + setTabBar(tabBar); + + // connecting tabbar signals + connect(tabBar, SIGNAL(tabCloseRequested(int)), this, SLOT(closeTab(int))); + connect(tabBar, SIGNAL(mouseMiddleClick(int)), this, SLOT(closeTab(int))); + + connect(tabBar, SIGNAL(newTabRequest()), this, SLOT(newCleanTab())); + + connect(tabBar, SIGNAL(cloneTab(int)), this, SLOT(cloneTab(int))); + connect(tabBar, SIGNAL(closeTab(int)), this, SLOT(closeTab(int))); + connect(tabBar, SIGNAL(closeOtherTabs(int)), this, SLOT(closeOtherTabs(int))); + connect(tabBar, SIGNAL(reloadTab(int)), this, SLOT(reloadTab(int))); + connect(tabBar, SIGNAL(detachTab(int)), this, SLOT(detachTab(int))); + connect(tabBar, SIGNAL(restoreClosedTab(int)), this, SLOT(restoreClosedTab(int))); + + // new tab button + KAction* a = new KAction(KIcon("tab-new"), i18n("New &Tab"), this); + _addTabButton->setDefaultAction(a); + _addTabButton->setAutoRaise(true); + _addTabButton->setToolButtonStyle(Qt::ToolButtonIconOnly); + connect(_addTabButton, SIGNAL(triggered(QAction *)), this, SLOT(newCleanTab())); + + connect(this, SIGNAL(currentChanged(int)), this, SLOT(currentChanged(int))); + + // FIXME: Manage sizes... + kDebug() << "SIZE: " << size(); + kDebug() << "SIZE HINT: " << sizeHint(); + + resize(sizeHint()); + +} + + +QSize TabWindow::sizeHint() const +{ + QRect desktopRect = QApplication::desktop()->screenGeometry(); + QSize size = desktopRect.size() * 0.8; + return size; +} + + +TabBar *TabWindow::tabBar() const +{ + TabBar *tabBar = qobject_cast(QTabWidget::tabBar()); + return tabBar; +} + + +WebWindow *TabWindow::currentWebWindow() const +{ + return webWindow(currentIndex()); +} + + +WebWindow *TabWindow::webWindow(int index) const +{ + WebWindow *tab = qobject_cast(this->widget(index)); + if (tab) + { + return tab; + } + + kDebug() << "WebWindow with index " << index << "not found. Returning NULL." ; + return 0; +} + + +WebWindow *TabWindow::prepareNewTab(WebPage *page) +{ + WebWindow *tab; + if (page) + tab = new WebWindow(page, this); + else + tab = new WebWindow(this); + + connect(tab, SIGNAL(titleChanged(QString)), this, SLOT(tabTitleChanged(QString))); + + connect(tab, SIGNAL(loadStarted()), this, SLOT(tabLoadStarted())); + connect(tab, SIGNAL(loadProgress(int)), this, SLOT(tabLoadProgress(int))); + connect(tab, SIGNAL(loadFinished(bool)), this, SLOT(tabLoadFinished(bool))); + + connect(tab, SIGNAL(pageCreated(WebPage *)), this, SLOT(pageCreated(WebPage *))); + + return tab; +} + + +void TabWindow::loadUrlInNewTab(const QUrl &url, TabHistory *history) +{ + WebWindow *tab = prepareNewTab(); + + // Now, the dirty jobs... + addTab(tab, i18n("new tab")); + tab->load(url); + + setCurrentWidget(tab); + + if (history) + { + history->applyHistory(tab->page()->history()); + } + + updateTabBar(); +} + + +void TabWindow::newCleanTab() +{ + QUrl u = QUrl::fromUserInput("/DATI/WEBPAGES/HomePage/index.htm"); + loadUrlInNewTab(u); +} + + +void TabWindow::pageCreated(WebPage *page) +{ + WebWindow *tab = prepareNewTab(page); + + // Now, the dirty jobs... + _openedTabsCounter++; + insertTab(currentIndex() + _openedTabsCounter, tab, i18n("new tab")); + + // Finally, update tab bar... + updateTabBar(); +} + + +void TabWindow::currentChanged(int newIndex) +{ + Q_UNUSED(newIndex); + + _openedTabsCounter = 0; +} + + +void TabWindow::resizeEvent(QResizeEvent *event) +{ + QTabWidget::resizeEvent(event); + updateTabBar(); +} + + +void TabWindow::updateTabBar() +{ + // update tab button position + static bool ButtonInCorner = false; + + int tabWidgetWidth = frameSize().width(); + int tabBarWidth = tabBar()->sizeHint().width(); + + if (tabBarWidth + _addTabButton->width() > tabWidgetWidth) + { + if (ButtonInCorner) + return; + setCornerWidget(_addTabButton); + ButtonInCorner = true; + } + else + { + if (ButtonInCorner) + { + setCornerWidget(0); + ButtonInCorner = false; + } + + _addTabButton->move(tabBarWidth, 0); + _addTabButton->show(); + } +} + + +void TabWindow::tabTitleChanged(const QString &title) +{ + WebWindow *tab = qobject_cast(sender()); + if (!tab) + return; + + QString tabTitle = title.isEmpty() ? i18n("(Untitled)") : title; + tabTitle.replace('&', "&&"); + + int index = indexOf(tab); + if (-1 != index) + { + setTabText(index, tabTitle); + } + + // TODO: What about window title? +} + + +void TabWindow::tabLoadStarted() +{ + WebWindow *tab = qobject_cast(sender()); + if (!tab) + return; + + int index = indexOf(tab); + if (index != -1) + { + QLabel *label = qobject_cast(tabBar()->tabButton(index, QTabBar::LeftSide)); + if (!label) + { + label = new QLabel(this); + } + + if (!label->movie()) + { + static QString loadingGitPath = KStandardDirs::locate("appdata" , "pics/loading.mng"); + + QMovie *movie = new QMovie(loadingGitPath, QByteArray(), label); + movie->setSpeed(50); + label->setMovie(movie); + movie->start(); + } + tabBar()->setTabButton(index, QTabBar::LeftSide, 0); + tabBar()->setTabButton(index, QTabBar::LeftSide, label); + } +} + + +void TabWindow::tabLoadProgress(int p) +{ + // FIXME: is this needed? + WebWindow *tab = qobject_cast(sender()); + if (!tab) + return; + + int index = indexOf(tab); + kDebug() << "LOADING TAB: " << index << ", PROGRESS: " << p; +} + + +void TabWindow::tabLoadFinished(bool ok) +{ + Q_UNUSED(ok); + + WebWindow *tab = qobject_cast(sender()); + if (!tab) + return; + + int index = indexOf(tab); + + if (-1 != index) + { + QLabel *label = qobject_cast(tabBar()->tabButton(index, QTabBar::LeftSide)); + + QMovie *movie = label->movie(); + movie->stop(); + delete movie; + + label->setMovie(0); + label->setPixmap(tab->icon().pixmap(16, 16)); + } +} + + +void TabWindow::cloneTab(int index) +{ + if (index < 0) + index = currentIndex(); + if (index < 0 || index >= count()) + return; + + QUrl u = webWindow(index)->url(); + QWebHistory* history = webWindow(index)->page()->history(); + TabHistory tHistory(history); + + loadUrlInNewTab(u, &tHistory); +} + + +void TabWindow::closeTab(int index, bool del) +{ + if (index < 0) + index = currentIndex(); + if (index < 0 || index >= count()) + return; + + WebWindow *tabToClose = webWindow(index); + if (!tabToClose) + return; + + // what to do if there is just one tab... + if (count() == 1) + { + kDebug() << "CANNOT CLOSE WINDOW FROM HERE..."; + QUrl u = QUrl::fromUserInput("/DATI/WEBPAGES/HomePage/index.htm"); + currentWebWindow()->load(u); + return; + } + + if (!tabToClose->url().isEmpty() + && tabToClose->url().scheme() != QLatin1String("about") + && !tabToClose->page()->settings()->testAttribute(QWebSettings::PrivateBrowsingEnabled) + ) + { + const int recentlyClosedTabsLimit = 8; + TabHistory history(tabToClose->page()->history()); + history.title = tabToClose->title(); + history.url = tabToClose->url().toString(); + + m_recentlyClosedTabs.removeAll(history); + if (m_recentlyClosedTabs.count() == recentlyClosedTabsLimit) + m_recentlyClosedTabs.removeLast(); + m_recentlyClosedTabs.prepend(history); + } + + removeTab(index); + updateTabBar(); // UI operation: do it ASAP!! + + if (del) + { + tabToClose->deleteLater(); + } +} + + +void TabWindow::closeOtherTabs(int index) +{ + if (index < 0) + index = currentIndex(); + if (index < 0 || index >= count()) + return; + + for (int i = count() - 1; i > index; --i) + { + closeTab(i); + } + + for (int i = index - 1; i >= 0; --i) + { + closeTab(i); + } +} + + +void TabWindow::reloadTab(int index) +{ + // When index is -1 index chooses the current tab + if (index < 0) + index = currentIndex(); + + if (index < 0 || index >= count()) + return; + + WebWindow *reloadingTab = webWindow(index); + QAction *action = reloadingTab->page()->action(QWebPage::Reload); + action->trigger(); +} + + +void TabWindow::reloadAllTabs() +{ + for (int i = 0; i < count(); ++i) + { + reloadTab(i); + } +} + + +void TabWindow::restoreClosedTab(int i) +{ + if (m_recentlyClosedTabs.isEmpty()) + return; + + TabHistory history = m_recentlyClosedTabs.takeAt(i); + + QUrl u = QUrl(history.url); + + loadUrlInNewTab(u, &history); + + // just to get sure... + m_recentlyClosedTabs.removeAll(history); +} diff --git a/src/tabwindow/tabwindow.h b/src/tabwindow/tabwindow.h new file mode 100644 index 00000000..147fac40 --- /dev/null +++ b/src/tabwindow/tabwindow.h @@ -0,0 +1,100 @@ +/*************************************************************************** + * 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) any later version. * + * * + * 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, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + + + +#ifndef TAB_WINDOW +#define TAB_WINDOW + + +#include + +class QLabel; +class QUrl; +class QToolButton; +class QWebHistory; + +class TabHistory; + +class TabBar; +class WebPage; +class WebWindow; + + +class TabWindow : public KTabWidget +{ + Q_OBJECT + +public: + TabWindow(QWidget *parent = 0); + + virtual QSize sizeHint() const; + + WebWindow* currentWebWindow() const; + WebWindow* webWindow(int index) const; + + TabBar* tabBar() const; + +public Q_SLOTS: + void loadUrlInNewTab(const QUrl &, TabHistory *history = 0); + void newCleanTab(); + +private: + /** + * Updates tabbar and add new tab button position + */ + void updateTabBar(); + + /** + * Prepares the new WebWindow to be open + */ + WebWindow *prepareNewTab(WebPage *page = 0); + +private Q_SLOTS: + void tabTitleChanged(const QString &); + + void tabLoadStarted(); + void tabLoadProgress(int); + void tabLoadFinished(bool); + + void pageCreated(WebPage *); + + void currentChanged(int); + + // Indexed slots + void cloneTab(int index = -1); + void closeTab(int index = -1, bool del = true); + void closeOtherTabs(int index = -1); + void reloadTab(int index = -1); + void reloadAllTabs(); + void restoreClosedTab(int i); + +protected: + virtual void resizeEvent(QResizeEvent *); + +private: + // the new tab button + QToolButton *_addTabButton; + + int _openedTabsCounter; + + QList m_recentlyClosedTabs; +}; + +#endif // TAB_WINDOW diff --git a/src/webwindow/webpage.cpp b/src/webwindow/webpage.cpp new file mode 100644 index 00000000..2c2d34e3 --- /dev/null +++ b/src/webwindow/webpage.cpp @@ -0,0 +1,60 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2008 Benjamin C. Meyer +* Copyright (C) 2008 Dirk Mueller +* Copyright (C) 2008 Urs Wolfer +* Copyright (C) 2008 Michael Howell +* Copyright (C) 2008-2012 by Andrea Diamantini +* Copyright (C) 2010 by Matthieu Gicquel +* Copyright (C) 2009-2010 Dawit Alemayehu +* +* +* 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 "webpage.h" +#include "webpage.moc" + +#include + + +WebPage::WebPage(QWidget *parent) + : KWebPage(parent) +{ +} + + +WebPage::~WebPage() +{ +} + + +WebPage *WebPage::createWindow(QWebPage::WebWindowType type) +{ + // added to manage web modal dialogs + if (type == QWebPage::WebModalDialog) + kDebug() << "Modal Dialog"; + + WebPage* p = new WebPage; + emit pageCreated(p); + return p; +} diff --git a/src/webwindow/webpage.h b/src/webwindow/webpage.h new file mode 100644 index 00000000..3631074b --- /dev/null +++ b/src/webwindow/webpage.h @@ -0,0 +1,54 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2008 Benjamin C. Meyer +* Copyright (C) 2008 Dirk Mueller +* Copyright (C) 2008 Urs Wolfer +* Copyright (C) 2008 Michael Howell +* Copyright (C) 2008-2012 by Andrea Diamantini +* Copyright (C) 2010 by Matthieu Gicquel +* +* +* 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 . +* +* ============================================================ */ + + +#ifndef WEBPAGE_H +#define WEBPAGE_H + +// KDE Includes +#include + + +class WebPage : public KWebPage +{ + Q_OBJECT + +public: + WebPage(QWidget *parent = 0); + ~WebPage(); + +protected: + WebPage *createWindow(WebWindowType type); + +Q_SIGNALS: + void pageCreated(WebPage *); +}; + +#endif diff --git a/src/webwindow/webwindow.cpp b/src/webwindow/webwindow.cpp new file mode 100644 index 00000000..4351f331 --- /dev/null +++ b/src/webwindow/webwindow.cpp @@ -0,0 +1,150 @@ +/*************************************************************************** + * 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) any later version. * + * * + * 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, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + + +#include "webwindow.h" +#include "webwindow.moc" + +#include "webpage.h" + +#include +#include +#include +#include + + +WebWindow::WebWindow(QWidget *parent) + : QWidget(parent) + , _view(new QWebView(this)) + , _edit(new QLineEdit(this)) +{ + WebPage *p = new WebPage(_view); + _view->setPage(p); + + // layout + QVBoxLayout *l = new QVBoxLayout; + l->addWidget(_edit); + l->addWidget(_view); + l->setContentsMargins(0, 0, 0, 0); + setLayout(l); + + setContentsMargins(0,0,0,0); + + // line edit signals + connect(_edit, SIGNAL(returnPressed()), this, SLOT(checkLoadUrl())); + + // url signal + connect(_view, SIGNAL(urlChanged(QUrl)), this, SLOT(setUrlText(QUrl))); + + // things changed signals + connect(_view, SIGNAL(titleChanged(QString)), this, SIGNAL(titleChanged(QString))); + + // load signals + connect(_view, SIGNAL(loadStarted()), this, SIGNAL(loadStarted())); + connect(_view, SIGNAL(loadProgress(int)), this, SIGNAL(loadProgress(int))); + connect(_view, SIGNAL(loadFinished(bool)), this, SIGNAL(loadFinished(bool))); + + // page signals + connect(p, SIGNAL(pageCreated(WebPage *)), this, SIGNAL(pageCreated(WebPage *))); +} + + +WebWindow::WebWindow(WebPage *page, QWidget *parent) + : QWidget(parent) + , _view(new QWebView(this)) + , _edit(new QLineEdit(this)) +{ + _view->setPage(page); + page->setParent(_view); + + // layout + QVBoxLayout *l = new QVBoxLayout; + l->addWidget(_edit); + l->addWidget(_view); + l->setContentsMargins(0, 0, 0, 0); + setLayout(l); + + setContentsMargins(0,0,0,0); + + // line edit signals + connect(_edit, SIGNAL(returnPressed()), this, SLOT(checkLoadUrl())); + + // url signal + connect(_view, SIGNAL(urlChanged(QUrl)), this, SLOT(setUrlText(QUrl))); + + // things changed signals + connect(_view, SIGNAL(titleChanged(QString)), this, SIGNAL(titleChanged(QString))); + + // load signals + connect(_view, SIGNAL(loadStarted()), this, SIGNAL(loadStarted())); + connect(_view, SIGNAL(loadProgress(int)), this, SIGNAL(loadProgress(int))); + connect(_view, SIGNAL(loadFinished(bool)), this, SIGNAL(loadFinished(bool))); + + // page signals + connect(page, SIGNAL(pageCreated(WebPage *)), this, SIGNAL(pageCreated(WebPage *))); + +} + + +void WebWindow::load(const QUrl &url) +{ + _view->load(url); +} + + +WebPage *WebWindow::page() +{ + if (!_view) + return 0; + + WebPage *p = qobject_cast(_view->page()); + return p; +} + + +void WebWindow::checkLoadUrl() +{ + QString urlString = _edit->text(); + QUrl u = QUrl::fromUserInput(urlString); + load(u); +} + + +void WebWindow::setUrlText(const QUrl &u) +{ + _edit->setText(u.toString()); +} + + +QUrl WebWindow::url() const +{ + return _view->url(); +} + + +QString WebWindow::title() const +{ + return _view->title(); +} + + +QIcon WebWindow::icon() const +{ + return _view->icon(); +} diff --git a/src/webwindow/webwindow.h b/src/webwindow/webwindow.h new file mode 100644 index 00000000..e5f68567 --- /dev/null +++ b/src/webwindow/webwindow.h @@ -0,0 +1,69 @@ +/*************************************************************************** + * 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) any later version. * + * * + * 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, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + + +#ifndef WEB_WINDOW +#define WEB_WINDOW + + +#include + + +class WebPage; + +class QWebView; +class QLineEdit; +class QUrl; + + +class WebWindow : public QWidget +{ + Q_OBJECT + +public: + WebWindow(QWidget *parent = 0); + WebWindow(WebPage *page, QWidget *parent = 0); + + void load(const QUrl &); + + WebPage *page(); + + QUrl url() const; + QString title() const; + QIcon icon() const; + +private Q_SLOTS: + void checkLoadUrl(); + void setUrlText(const QUrl &); + +Q_SIGNALS: + void titleChanged(QString); + + void loadStarted(); + void loadProgress(int); + void loadFinished(bool); + + void pageCreated(WebPage *); + +private: + QWebView *_view; + QLineEdit *_edit; +}; + +#endif // WEB_WINDOW -- cgit v1.2.1