Commit fcebd431 authored by Dirk Wilden's avatar Dirk Wilden

helpWidget now nearly perfect :D

added Tabs and search functionality

git-svn-id: http://www.openflipper.org/svnrepo/OpenFlipper/branches/Free@3643 383ad7c9-94d9-4d36-a494-682f7c89f535
parent ba856319
......@@ -12,12 +12,12 @@
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
//
// OpenFlipper 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 Lesser General Public License for more details.
//
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenFlipper. If not, see <http://www.gnu.org/licenses/>.
//
......@@ -45,34 +45,50 @@
#include <OpenFlipper/common/GlobalOptions.hh>
//== IMPLEMENTATION ==========================================================
//== IMPLEMENTATION ==========================================================
void CoreWidget::showHelpBrowserUser( ) {
if ( OpenFlipper::Options::nogui() )
return;
if ( helpBrowserUser_ == 0 ) {
helpBrowserUser_ = new HelpWidget( this ,true);
}
//show the widget centered
QPoint center;
center.setX( x() + width() / 2 );
center.setY( y() + height() / 2 );
helpBrowserUser_->setGeometry(center.x() - helpBrowserUser_->width() / 2,
center.y() - helpBrowserUser_->height()/ 2, helpBrowserUser_->width(), helpBrowserUser_->height());
helpBrowserUser_->show();
}
void CoreWidget::showHelpBrowserDeveloper( ) {
if ( OpenFlipper::Options::nogui() )
return;
if ( helpBrowserDeveloper_ == 0 ) {
helpBrowserDeveloper_ = new HelpWidget( this ,false);
}
//show the widget centered
QPoint center;
center.setX( x() + width() / 2 );
center.setY( y() + height() / 2 );
helpBrowserDeveloper_->setGeometry(center.x() - helpBrowserDeveloper_->width() / 2,
center.y() - helpBrowserDeveloper_->height()/ 2, helpBrowserDeveloper_->width(), helpBrowserDeveloper_->height());
helpBrowserDeveloper_->show();
}
//=============================================================================
#include "findEdit.hh"
#include <QKeyEvent>
findEdit::findEdit(QWidget* parent) : QLineEdit(parent)
{
connect(this, SIGNAL(textEdited(const QString&)), this, SLOT(slotTextEdited(const QString&)) );
}
void findEdit::keyPressEvent(QKeyEvent* event)
{
if (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return)
emit find();
else if (event->key() == Qt::Key_F3)
emit find();
else if (event->key() == Qt::Key_Escape)
emit close();
else
QLineEdit::keyPressEvent(event);
}
void findEdit::slotTextEdited(const QString&)
{
emit textEdited();
}
#ifndef FINDEDIT_HH
#define FINDEDIT_HH
#include <QLineEdit>
class findEdit : public QLineEdit
{
Q_OBJECT
signals:
void find();
void close();
void textEdited();
public:
findEdit(QWidget *parent = 0);
protected:
void keyPressEvent( QKeyEvent* event );
private slots:
void slotTextEdited(const QString& /*text*/);
};
#endif //FINDEDIT_HH
......@@ -3,7 +3,6 @@
#include <OpenFlipper/common/GlobalOptions.hh>
#include <QtWebKit>
#include <iostream>
HelpWidget::HelpWidget(QWidget *parent, bool _user)
......@@ -14,73 +13,111 @@ HelpWidget::HelpWidget(QWidget *parent, bool _user)
QString iconPath = OpenFlipper::Options::iconDirStr() + OpenFlipper::Options::dirSeparator();
//create toolbar
QAction* action = toolBar->addAction(QIcon(iconPath + "arrow-left.png"), "Back");
connect(action, SIGNAL(triggered()), webView, SLOT(back()));
action = toolBar->addAction(QIcon(iconPath + "arrow-right.png"), "Forward");
connect(action, SIGNAL(triggered()), webView, SLOT(forward()));
action = toolBar->addAction(QIcon(iconPath + "go-home.png"), "Home");
back_ = toolBar->addAction(QIcon(iconPath + "arrow-left.png"), "Back");
forward_ = toolBar->addAction(QIcon(iconPath + "arrow-right.png"), "Forward");
QAction* action = toolBar->addAction(QIcon(iconPath + "go-home.png"), "Home");
connect(action, SIGNAL(triggered()), this, SLOT(goHome()));
toolBar->addSeparator();
action = toolBar->addAction(QIcon(iconPath + "edit-find.png"), "Find text");
connect(action, SIGNAL(triggered()), this, SLOT(showFind()));
//finding
initFindFrame();
//splitter position
QList<int> wsizes( splitter->sizes() );
wsizes[0] = 30;
wsizes[1] = 70;
splitter->setSizes(wsizes);
//tab buttons
QPushButton* closeTabButton = new QPushButton();
QPushButton* addTabButton = new QPushButton();
closeTabButton->setIcon(QIcon(iconPath+"tab-close.png"));
addTabButton->setIcon(QIcon(iconPath+"tab-new.png"));
addTabButton->setMaximumSize(26,26);
tabs->setCornerWidget(closeTabButton, Qt::TopRightCorner);
tabs->setCornerWidget(addTabButton, Qt::TopLeftCorner);
connect( closeTabButton, SIGNAL(clicked()), this, SLOT(closeCurrentTab()) );
connect( addTabButton, SIGNAL(clicked()), this, SLOT(duplicateCurrentTab()) );
QIcon icon;
icon.addFile(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"window-close.png");
actionClose->setIcon(icon);
baseDir_ = OpenFlipper::Options::applicationDirStr() +
baseDir_ = OpenFlipper::Options::applicationDirStr() +
OpenFlipper::Options::dirSeparator() + "Docs";
if ( _user ) {
baseDir_ += OpenFlipper::Options::dirSeparator() + "User" +
OpenFlipper::Options::dirSeparator();
startFile_ = baseDir_ + "OpenFlipperUserDoc.html";
} else {
baseDir_ += OpenFlipper::Options::dirSeparator() + "Developer" +
OpenFlipper::Options::dirSeparator();
startFile_ = baseDir_ + "OpenFlipperDeveloperDoc.html";
}
connect(webView, SIGNAL( loadFinished(bool) ), this, SLOT( loadFinished(bool) ));
webView->load( QUrl(startFile_) );
currentView_ = new webView();
tabs->removeTab(0);
newTab(currentView_);
setConnections();
webView->history()->clear();
currentView_->load( QUrl(startFile_) );
connect( actionClose , SIGNAL(triggered() ) , this, SLOT(hide()) );
connect( closeButton , SIGNAL(clicked() ) , this, SLOT(hide()) );
generateTree();
tree->setHeaderHidden( true );
tabs->setContextMenuPolicy( Qt::CustomContextMenu );
tree->setContextMenuPolicy( Qt::CustomContextMenu );
contextMenu_ = new QMenu();
connect( tree, SIGNAL(itemClicked(QTreeWidgetItem*, int)), this, SLOT(treeClicked(QTreeWidgetItem*,int)) );
connect( tree, SIGNAL(customContextMenuRequested (const QPoint &)), this, SLOT(showContextMenu(const QPoint &)));
connect( tabs, SIGNAL(customContextMenuRequested (const QPoint &)), this, SLOT(showContextMenu(const QPoint &)));
connect( tabs, SIGNAL(currentChanged(int)), this, SLOT(tabChanged(int)) );
}
void HelpWidget::loadFinished(bool ok)
///update the signals/slots which are only active on the visible webView
void HelpWidget::setConnections()
{
back_->disconnect();
connect(back_, SIGNAL(triggered()), currentView_, SLOT(back()));
forward_->disconnect();
connect(forward_, SIGNAL(triggered()), currentView_, SLOT(forward()));
}
if (ok)
tabWidget->setTabText(tabWidget->currentIndex(), webView->page()->mainFrame()->title());
void HelpWidget::loadFinished(bool)
{
// std::cerr << "history " << webView->history()->items().count() << std::endl;
//
//
// if ( webView->url().path() != QUrl(startFile_).path() || !ok )
// return;
//
//
// QDir docDir = QDir(baseDir_);
// QStringList plugins = docDir.entryList ( QDir::AllDirs | QDir::NoDotAndDotDot);
//
//
// QString pluginHtml;
//
// for ( int i = 0 ; i < plugins.size(); ++i )
//
// for ( int i = 0 ; i < plugins.size(); ++i )
// if ( plugins[i].contains("Plugin-") )
// pluginHtml.append( "<a href=\"" + plugins[i] + OpenFlipper::Options::dirSeparator()
// + "index.html\">" + plugins[i] + "</a><br>" );
//
//
// QString source = webView->page()->currentFrame()->toHtml();
//
//
// source = source.replace("REPLACEWITHPLUGINLINKS",pluginHtml);
//
//
// webView->page()->currentFrame()->setHtml(source, QUrl(baseDir_));
}
......@@ -88,7 +125,7 @@ void HelpWidget::loadFinished(bool ok)
/// go to home dir
void HelpWidget::goHome()
{
webView->load( QUrl(startFile_) );
currentView_->load( QUrl(startFile_) );
}
///generate the documentation tree
......@@ -123,7 +160,7 @@ void HelpWidget::generateTree(){
else{
currentItem = new QTreeWidgetItem(QString(title + "," + names.first()).split(","));
if (parents.first() == 0)
tree->addTopLevelItem( currentItem );
else
......@@ -176,7 +213,7 @@ QString HelpWidget::getTitle(QString htmlFile){
}
/// the user clicked on an item in the treeWidget
void HelpWidget::treeClicked(QTreeWidgetItem* item, int column ){
void HelpWidget::treeClicked(QTreeWidgetItem* item, int /*column*/ ){
QTreeWidgetItem* parent = item->parent();
QString path = baseDir_;
......@@ -185,6 +222,224 @@ void HelpWidget::treeClicked(QTreeWidgetItem* item, int column ){
path += parent->text(1) + OpenFlipper::Options::dirSeparator();
parent = parent->parent();
}
webView->load( QUrl(path + item->text(1) + OpenFlipper::Options::dirSeparator() + "index.html") );
}
\ No newline at end of file
currentView_->load( QUrl(path + item->text(1) + OpenFlipper::Options::dirSeparator() + "index.html") );
}
///the url changed
void HelpWidget::urlChanged(const QUrl& /*url*/){
back_->setEnabled( currentView_->history()->canGoBack() );
forward_->setEnabled( currentView_->history()->canGoForward() );
}
/// add a new Tab to the Tabs
void HelpWidget::newTab(QWebView* _webView){
webView* view = dynamic_cast< webView* > (_webView);
connect(view, SIGNAL(titleChanged(const QString&)), this, SLOT(titleChanged(const QString&)));
connect(view, SIGNAL(windowCreated(QWebView*)), this, SLOT(newTab(QWebView*)) );
connect(view, SIGNAL( loadFinished(bool) ), this, SLOT( loadFinished(bool) ));
connect(view, SIGNAL( find() ), this, SLOT( showFind() ));
connect(view, SIGNAL( findNext() ), this, SLOT( findNext1() ));
connect(view, SIGNAL(urlChanged(const QUrl &)), this, SLOT(urlChanged(const QUrl &)) );
tabs->addTab(view, "");
}
/// the title of one of the tabs changed
void HelpWidget::titleChanged(const QString & title)
{
for(int i=0; i < tabs->count(); i++)
if (tabs->widget(i) == sender())
tabs->setTabText(i, title);
}
/// current tab changed
void HelpWidget::tabChanged(int _index)
{
currentView_ = dynamic_cast< webView* > (tabs->widget(_index));
setConnections();
back_->setEnabled( currentView_->history()->canGoBack() );
forward_->setEnabled( currentView_->history()->canGoForward() );
}
/// close the current tab
void HelpWidget::closeCurrentTab()
{
if (tabs->count() > 1)
tabs->removeTab( tabs->currentIndex() );
}
/// add a duplicate of the current Tab to the TabWidget
void HelpWidget::duplicateCurrentTab()
{
webView* newView = new webView();
newView->load( currentView_->url() );
newTab(newView);
tabs->setCurrentIndex(tabs->count()-1);
}
//----------------------------------------------------------------------------
// Finding
//----------------------------------------------------------------------------
///initialize the widgets corresponding to finding
void HelpWidget::initFindFrame()
{
findText_ = new findEdit();
//set icons
QString iconPath = OpenFlipper::Options::iconDirStr() + OpenFlipper::Options::dirSeparator();
findClose->setIcon( QIcon(iconPath + "application-exit.png") );
findPrev->setIcon( QIcon(iconPath + "arrow-left.png") );
findNext->setIcon( QIcon(iconPath + "arrow-right.png") );
//connect signals
connect(findText_, SIGNAL(find()), this, SLOT(findNext1()));
connect(findText_, SIGNAL(textEdited()), this, SLOT(findNext1()));
connect(findText_, SIGNAL(close()), findFrame, SLOT(hide()));
connect(findClose, SIGNAL(clicked()), findFrame, SLOT(hide()));
connect(findNext, SIGNAL(clicked()), this, SLOT(findNext1()));
connect(findPrev, SIGNAL(clicked()), this, SLOT(findPrev1()));
//set layout
QHBoxLayout *layout = new QHBoxLayout;
layout->addWidget( findClose );
layout->addWidget( findText_ );
layout->addWidget( findPrev );
layout->addWidget( findNext );
layout->addWidget( findSensitive );
layout->addStretch();
findFrame->setLayout(layout);
findFrame->hide();
}
///show the find frame under the current page
void HelpWidget::showFind(){
findFrame->setVisible( true );
findText_->selectAll();
findText_->setFocus(Qt::OtherFocusReason);
}
/// find the next element in the text that fits the search term
void HelpWidget::findNext1()
{
if (findText_->text() == ""){
//TODO do something that clears the selection
}
if ( findSensitive->isChecked() )
currentView_->findText( findText_->text() , QWebPage::FindCaseSensitively | QWebPage::FindWrapsAroundDocument);
else
currentView_->findText( findText_->text() , QWebPage::FindWrapsAroundDocument);
}
/// find the previous element in the text that fits the search term
void HelpWidget::findPrev1()
{
if ( findSensitive->isChecked() )
currentView_->findText( findText_->text() ,
QWebPage::FindBackward | QWebPage::FindCaseSensitively | QWebPage::FindWrapsAroundDocument);
else
currentView_->findText( findText_->text() , QWebPage::FindBackward | QWebPage::FindWrapsAroundDocument);
}
//----------------------------------------------------------------------------
// Context Menu
//----------------------------------------------------------------------------
///show the context menu
void HelpWidget::showContextMenu(const QPoint & _pos)
{
QObject* treeObj = dynamic_cast< QObject* > (tree);
if(sender() == treeObj){
//sender was the treeWidget
lastContextMenu_ = tree->mapToGlobal(_pos);
contextMenu_->clear();
QAction* open = contextMenu_->addAction("Open");
QAction* openNew = contextMenu_->addAction("Open in new tab");
connect(open, SIGNAL(triggered()), this, SLOT(contextOpenTab()));
connect(openNew, SIGNAL(triggered()), this, SLOT(contextOpenNewTab()));
}else{
//sender was the tabWidget
lastContextMenu_ = tabs->mapToGlobal(_pos);
//first check if the tabBar was clicked
QWidget* w = tabs->childAt(tabs->mapFromGlobal(lastContextMenu_));
if(w == 0) return;
QTabBar* tabBar = dynamic_cast< QTabBar* > (w);
if (tabBar == 0) return;
int id = tabBar->tabAt( tabBar->mapFromGlobal(lastContextMenu_) );
if (id == -1) return;
//set up the menu
contextMenu_->clear();
QAction* close = contextMenu_->addAction("Close Tab");
connect(close, SIGNAL(triggered()), this, SLOT(contextCloseTab()));
}
//finally show the menu
contextMenu_->popup(lastContextMenu_);
}
///open content in current tab initiated by contextMenu
void HelpWidget::contextOpenTab()
{
QTreeWidgetItem* item = tree->itemAt(tree->mapFromGlobal(lastContextMenu_));
if (item != 0)
treeClicked(item, 0 );
}
///open content in new tab initiated by contextMenu
void HelpWidget::contextOpenNewTab()
{
QTreeWidgetItem* item = tree->itemAt(tree->mapFromGlobal(lastContextMenu_));
if (item != 0){
duplicateCurrentTab();
treeClicked(item, 0 );
}
}
///close tab initiated by contextMenu
void HelpWidget::contextCloseTab()
{
QWidget* w = tabs->childAt(tabs->mapFromGlobal(lastContextMenu_));
if(w != 0){
QTabBar* tabBar = dynamic_cast< QTabBar* > (w);
if (tabBar != 0){
int id = tabBar->tabAt( tabBar->mapFromGlobal(lastContextMenu_) );
if (id != -1)
tabs->removeTab( id );
}
}
}
#include "ui_helpWidget.hh"
#include <QtGui>
#include "webView.hh"
#include "findEdit.hh"
class HelpWidget : public QMainWindow, public Ui::HelpWidget
{
Q_OBJECT
......@@ -14,12 +17,44 @@ class HelpWidget : public QMainWindow, public Ui::HelpWidget
void generateTree();
void setConnections();
QString getTitle(QString htmlFile);
QAction* back_;
QAction* forward_;
webView* currentView_;
private slots:
void loadFinished( bool ok );
void loadFinished( bool ok );
void goHome();
void treeClicked(QTreeWidgetItem* item, int column );
void urlChanged(const QUrl& url);
void newTab(QWebView* _webView);
void titleChanged (const QString & title );
void tabChanged (int _index);
void closeCurrentTab();
void duplicateCurrentTab();
//finding
private:
findEdit* findText_;
private slots:
void showFind();
void findNext1();
void findPrev1();
void initFindFrame();
//context menu
private:
QMenu* contextMenu_;
QPoint lastContextMenu_;
private slots:
void showContextMenu(const QPoint& _pos);
void contextOpenTab();
void contextOpenNewTab();
void contextCloseTab();
};
......@@ -5,97 +5,178 @@
<rect>
<x>0</x>
<y>0</y>
<width>1008</width>
<height>813</height>
<width>805</width>
<height>680</height>
</rect>
</property>
<property name="windowTitle" >
<string>Help Browser</string>
</property>
<widget class="QWidget" name="centralwidget" >
<property name="geometry" >
<rect>
<x>0</x>
<y>35</y>
<width>1008</width>
<height>757</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2" >
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2" >
<item>
<widget class="QTreeWidget" name="tree" >
<property name="minimumSize" >
<size>
<width>160</width>
<height>0</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="QTabWidget" name="tabWidget" >
<property name="currentIndex" >
<number>0</number>
</property>
<widget class="QWidget" name="tab" >
<property name="geometry" >
<rect>