| 1 | /****************************************************************************
|
|---|
| 2 | ** $Id: helpwindow.cpp 2 2005-11-16 15:49:26Z dmik $
|
|---|
| 3 | **
|
|---|
| 4 | ** Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
|
|---|
| 5 | **
|
|---|
| 6 | ** This file is part of an example program for Qt. This example
|
|---|
| 7 | ** program may be used, distributed and modified without limitation.
|
|---|
| 8 | **
|
|---|
| 9 | *****************************************************************************/
|
|---|
| 10 |
|
|---|
| 11 | #include "helpwindow.h"
|
|---|
| 12 | #include <qstatusbar.h>
|
|---|
| 13 | #include <qpixmap.h>
|
|---|
| 14 | #include <qpopupmenu.h>
|
|---|
| 15 | #include <qmenubar.h>
|
|---|
| 16 | #include <qtoolbar.h>
|
|---|
| 17 | #include <qtoolbutton.h>
|
|---|
| 18 | #include <qiconset.h>
|
|---|
| 19 | #include <qfile.h>
|
|---|
| 20 | #include <qtextstream.h>
|
|---|
| 21 | #include <qstylesheet.h>
|
|---|
| 22 | #include <qmessagebox.h>
|
|---|
| 23 | #include <qfiledialog.h>
|
|---|
| 24 | #include <qapplication.h>
|
|---|
| 25 | #include <qcombobox.h>
|
|---|
| 26 | #include <qevent.h>
|
|---|
| 27 | #include <qlineedit.h>
|
|---|
| 28 | #include <qobjectlist.h>
|
|---|
| 29 | #include <qfileinfo.h>
|
|---|
| 30 | #include <qfile.h>
|
|---|
| 31 | #include <qdatastream.h>
|
|---|
| 32 | #include <qprinter.h>
|
|---|
| 33 | #include <qsimplerichtext.h>
|
|---|
| 34 | #include <qpainter.h>
|
|---|
| 35 | #include <qpaintdevicemetrics.h>
|
|---|
| 36 |
|
|---|
| 37 | #include <ctype.h>
|
|---|
| 38 |
|
|---|
| 39 | HelpWindow::HelpWindow( const QString& home_, const QString& _path,
|
|---|
| 40 | QWidget* parent, const char *name )
|
|---|
| 41 | : QMainWindow( parent, name, WDestructiveClose ),
|
|---|
| 42 | pathCombo( 0 )
|
|---|
| 43 | {
|
|---|
| 44 | readHistory();
|
|---|
| 45 | readBookmarks();
|
|---|
| 46 |
|
|---|
| 47 | browser = new QTextBrowser( this );
|
|---|
| 48 |
|
|---|
| 49 | browser->mimeSourceFactory()->setFilePath( _path );
|
|---|
| 50 | browser->setFrameStyle( QFrame::Panel | QFrame::Sunken );
|
|---|
| 51 | connect( browser, SIGNAL( sourceChanged(const QString& ) ),
|
|---|
| 52 | this, SLOT( sourceChanged( const QString&) ) );
|
|---|
| 53 |
|
|---|
| 54 | setCentralWidget( browser );
|
|---|
| 55 |
|
|---|
| 56 | if ( !home_.isEmpty() )
|
|---|
| 57 | browser->setSource( home_ );
|
|---|
| 58 |
|
|---|
| 59 | connect( browser, SIGNAL( highlighted( const QString&) ),
|
|---|
| 60 | statusBar(), SLOT( message( const QString&)) );
|
|---|
| 61 |
|
|---|
| 62 | resize( 640,700 );
|
|---|
| 63 |
|
|---|
| 64 | QPopupMenu* file = new QPopupMenu( this );
|
|---|
| 65 | file->insertItem( tr("&New Window"), this, SLOT( newWindow() ), CTRL+Key_N );
|
|---|
| 66 | file->insertItem( tr("&Open File"), this, SLOT( openFile() ), CTRL+Key_O );
|
|---|
| 67 | file->insertItem( tr("&Print"), this, SLOT( print() ), CTRL+Key_P );
|
|---|
| 68 | file->insertSeparator();
|
|---|
| 69 | file->insertItem( tr("&Close"), this, SLOT( close() ), CTRL+Key_Q );
|
|---|
| 70 | file->insertItem( tr("E&xit"), qApp, SLOT( closeAllWindows() ), CTRL+Key_X );
|
|---|
| 71 |
|
|---|
| 72 | // The same three icons are used twice each.
|
|---|
| 73 | QIconSet icon_back( QPixmap("back.xpm") );
|
|---|
| 74 | QIconSet icon_forward( QPixmap("forward.xpm") );
|
|---|
| 75 | QIconSet icon_home( QPixmap("home.xpm") );
|
|---|
| 76 |
|
|---|
| 77 | QPopupMenu* go = new QPopupMenu( this );
|
|---|
| 78 | backwardId = go->insertItem( icon_back,
|
|---|
| 79 | tr("&Backward"), browser, SLOT( backward() ),
|
|---|
| 80 | CTRL+Key_Left );
|
|---|
| 81 | forwardId = go->insertItem( icon_forward,
|
|---|
| 82 | tr("&Forward"), browser, SLOT( forward() ),
|
|---|
| 83 | CTRL+Key_Right );
|
|---|
| 84 | go->insertItem( icon_home, tr("&Home"), browser, SLOT( home() ) );
|
|---|
| 85 |
|
|---|
| 86 | QPopupMenu* help = new QPopupMenu( this );
|
|---|
| 87 | help->insertItem( tr("&About"), this, SLOT( about() ) );
|
|---|
| 88 | help->insertItem( tr("About &Qt"), this, SLOT( aboutQt() ) );
|
|---|
| 89 |
|
|---|
| 90 | hist = new QPopupMenu( this );
|
|---|
| 91 | QStringList::Iterator it = history.begin();
|
|---|
| 92 | for ( ; it != history.end(); ++it )
|
|---|
| 93 | mHistory[ hist->insertItem( *it ) ] = *it;
|
|---|
| 94 | connect( hist, SIGNAL( activated( int ) ),
|
|---|
| 95 | this, SLOT( histChosen( int ) ) );
|
|---|
| 96 |
|
|---|
| 97 | bookm = new QPopupMenu( this );
|
|---|
| 98 | bookm->insertItem( tr( "Add Bookmark" ), this, SLOT( addBookmark() ) );
|
|---|
| 99 | bookm->insertSeparator();
|
|---|
| 100 |
|
|---|
| 101 | QStringList::Iterator it2 = bookmarks.begin();
|
|---|
| 102 | for ( ; it2 != bookmarks.end(); ++it2 )
|
|---|
| 103 | mBookmarks[ bookm->insertItem( *it2 ) ] = *it2;
|
|---|
| 104 | connect( bookm, SIGNAL( activated( int ) ),
|
|---|
| 105 | this, SLOT( bookmChosen( int ) ) );
|
|---|
| 106 |
|
|---|
| 107 | menuBar()->insertItem( tr("&File"), file );
|
|---|
| 108 | menuBar()->insertItem( tr("&Go"), go );
|
|---|
| 109 | menuBar()->insertItem( tr( "History" ), hist );
|
|---|
| 110 | menuBar()->insertItem( tr( "Bookmarks" ), bookm );
|
|---|
| 111 | menuBar()->insertSeparator();
|
|---|
| 112 | menuBar()->insertItem( tr("&Help"), help );
|
|---|
| 113 |
|
|---|
| 114 | menuBar()->setItemEnabled( forwardId, FALSE);
|
|---|
| 115 | menuBar()->setItemEnabled( backwardId, FALSE);
|
|---|
| 116 | connect( browser, SIGNAL( backwardAvailable( bool ) ),
|
|---|
| 117 | this, SLOT( setBackwardAvailable( bool ) ) );
|
|---|
| 118 | connect( browser, SIGNAL( forwardAvailable( bool ) ),
|
|---|
| 119 | this, SLOT( setForwardAvailable( bool ) ) );
|
|---|
| 120 |
|
|---|
| 121 |
|
|---|
| 122 | QToolBar* toolbar = new QToolBar( this );
|
|---|
| 123 | addToolBar( toolbar, "Toolbar");
|
|---|
| 124 | QToolButton* button;
|
|---|
| 125 |
|
|---|
| 126 | button = new QToolButton( icon_back, tr("Backward"), "", browser, SLOT(backward()), toolbar );
|
|---|
| 127 | connect( browser, SIGNAL( backwardAvailable(bool) ), button, SLOT( setEnabled(bool) ) );
|
|---|
| 128 | button->setEnabled( FALSE );
|
|---|
| 129 | button = new QToolButton( icon_forward, tr("Forward"), "", browser, SLOT(forward()), toolbar );
|
|---|
| 130 | connect( browser, SIGNAL( forwardAvailable(bool) ), button, SLOT( setEnabled(bool) ) );
|
|---|
| 131 | button->setEnabled( FALSE );
|
|---|
| 132 | button = new QToolButton( icon_home, tr("Home"), "", browser, SLOT(home()), toolbar );
|
|---|
| 133 |
|
|---|
| 134 | toolbar->addSeparator();
|
|---|
| 135 |
|
|---|
| 136 | pathCombo = new QComboBox( TRUE, toolbar );
|
|---|
| 137 | connect( pathCombo, SIGNAL( activated( const QString & ) ),
|
|---|
| 138 | this, SLOT( pathSelected( const QString & ) ) );
|
|---|
| 139 | toolbar->setStretchableWidget( pathCombo );
|
|---|
| 140 | setRightJustification( TRUE );
|
|---|
| 141 | setDockEnabled( DockLeft, FALSE );
|
|---|
| 142 | setDockEnabled( DockRight, FALSE );
|
|---|
| 143 |
|
|---|
| 144 | pathCombo->insertItem( home_ );
|
|---|
| 145 | browser->setFocus();
|
|---|
| 146 |
|
|---|
| 147 | }
|
|---|
| 148 |
|
|---|
| 149 |
|
|---|
| 150 | void HelpWindow::setBackwardAvailable( bool b)
|
|---|
| 151 | {
|
|---|
| 152 | menuBar()->setItemEnabled( backwardId, b);
|
|---|
| 153 | }
|
|---|
| 154 |
|
|---|
| 155 | void HelpWindow::setForwardAvailable( bool b)
|
|---|
| 156 | {
|
|---|
| 157 | menuBar()->setItemEnabled( forwardId, b);
|
|---|
| 158 | }
|
|---|
| 159 |
|
|---|
| 160 |
|
|---|
| 161 | void HelpWindow::sourceChanged( const QString& url )
|
|---|
| 162 | {
|
|---|
| 163 | if ( browser->documentTitle().isNull() )
|
|---|
| 164 | setCaption( "Qt Example - Helpviewer - " + url );
|
|---|
| 165 | else
|
|---|
| 166 | setCaption( "Qt Example - Helpviewer - " + browser->documentTitle() ) ;
|
|---|
| 167 |
|
|---|
| 168 | if ( !url.isEmpty() && pathCombo ) {
|
|---|
| 169 | bool exists = FALSE;
|
|---|
| 170 | int i;
|
|---|
| 171 | for ( i = 0; i < pathCombo->count(); ++i ) {
|
|---|
| 172 | if ( pathCombo->text( i ) == url ) {
|
|---|
| 173 | exists = TRUE;
|
|---|
| 174 | break;
|
|---|
| 175 | }
|
|---|
| 176 | }
|
|---|
| 177 | if ( !exists ) {
|
|---|
| 178 | pathCombo->insertItem( url, 0 );
|
|---|
| 179 | pathCombo->setCurrentItem( 0 );
|
|---|
| 180 | mHistory[ hist->insertItem( url ) ] = url;
|
|---|
| 181 | } else
|
|---|
| 182 | pathCombo->setCurrentItem( i );
|
|---|
| 183 | }
|
|---|
| 184 | }
|
|---|
| 185 |
|
|---|
| 186 | HelpWindow::~HelpWindow()
|
|---|
| 187 | {
|
|---|
| 188 | history = mHistory.values();
|
|---|
| 189 |
|
|---|
| 190 | QFile f( QDir::currentDirPath() + "/.history" );
|
|---|
| 191 | f.open( IO_WriteOnly );
|
|---|
| 192 | QDataStream s( &f );
|
|---|
| 193 | s << history;
|
|---|
| 194 | f.close();
|
|---|
| 195 |
|
|---|
| 196 | bookmarks = mBookmarks.values();
|
|---|
| 197 |
|
|---|
| 198 | QFile f2( QDir::currentDirPath() + "/.bookmarks" );
|
|---|
| 199 | f2.open( IO_WriteOnly );
|
|---|
| 200 | QDataStream s2( &f2 );
|
|---|
| 201 | s2 << bookmarks;
|
|---|
| 202 | f2.close();
|
|---|
| 203 | }
|
|---|
| 204 |
|
|---|
| 205 | void HelpWindow::about()
|
|---|
| 206 | {
|
|---|
| 207 | QMessageBox::about( this, "HelpViewer Example",
|
|---|
| 208 | "<p>This example implements a simple HTML help viewer "
|
|---|
| 209 | "using Qt's rich text capabilities</p>"
|
|---|
| 210 | "<p>It's just about 400 lines of C++ code, so don't expect too much :-)</p>"
|
|---|
| 211 | );
|
|---|
| 212 | }
|
|---|
| 213 |
|
|---|
| 214 |
|
|---|
| 215 | void HelpWindow::aboutQt()
|
|---|
| 216 | {
|
|---|
| 217 | QMessageBox::aboutQt( this, "QBrowser" );
|
|---|
| 218 | }
|
|---|
| 219 |
|
|---|
| 220 | void HelpWindow::openFile()
|
|---|
| 221 | {
|
|---|
| 222 | #ifndef QT_NO_FILEDIALOG
|
|---|
| 223 | QString fn = QFileDialog::getOpenFileName( QString::null, QString::null, this );
|
|---|
| 224 | if ( !fn.isEmpty() )
|
|---|
| 225 | browser->setSource( fn );
|
|---|
| 226 | #endif
|
|---|
| 227 | }
|
|---|
| 228 |
|
|---|
| 229 | void HelpWindow::newWindow()
|
|---|
| 230 | {
|
|---|
| 231 | ( new HelpWindow(browser->source(), "qbrowser") )->show();
|
|---|
| 232 | }
|
|---|
| 233 |
|
|---|
| 234 | void HelpWindow::print()
|
|---|
| 235 | {
|
|---|
| 236 | #ifndef QT_NO_PRINTER
|
|---|
| 237 | QPrinter printer( QPrinter::HighResolution );
|
|---|
| 238 | printer.setFullPage(TRUE);
|
|---|
| 239 | if ( printer.setup( this ) ) {
|
|---|
| 240 | QPainter p( &printer );
|
|---|
| 241 | if( !p.isActive() ) // starting printing failed
|
|---|
| 242 | return;
|
|---|
| 243 | QPaintDeviceMetrics metrics(p.device());
|
|---|
| 244 | int dpiy = metrics.logicalDpiY();
|
|---|
| 245 | int margin = (int) ( (2/2.54)*dpiy ); // 2 cm margins
|
|---|
| 246 | QRect body( margin, margin, metrics.width() - 2*margin, metrics.height() - 2*margin );
|
|---|
| 247 | QSimpleRichText richText( browser->text(),
|
|---|
| 248 | QFont(),
|
|---|
| 249 | browser->context(),
|
|---|
| 250 | browser->styleSheet(),
|
|---|
| 251 | browser->mimeSourceFactory(),
|
|---|
| 252 | body.height() );
|
|---|
| 253 | richText.setWidth( &p, body.width() );
|
|---|
| 254 | QRect view( body );
|
|---|
| 255 | int page = 1;
|
|---|
| 256 | do {
|
|---|
| 257 | richText.draw( &p, body.left(), body.top(), view, colorGroup() );
|
|---|
| 258 | view.moveBy( 0, body.height() );
|
|---|
| 259 | p.translate( 0 , -body.height() );
|
|---|
| 260 | p.drawText( view.right() - p.fontMetrics().width( QString::number(page) ),
|
|---|
| 261 | view.bottom() + p.fontMetrics().ascent() + 5, QString::number(page) );
|
|---|
| 262 | if ( view.top() >= richText.height() )
|
|---|
| 263 | break;
|
|---|
| 264 | printer.newPage();
|
|---|
| 265 | page++;
|
|---|
| 266 | } while (TRUE);
|
|---|
| 267 | }
|
|---|
| 268 | #endif
|
|---|
| 269 | }
|
|---|
| 270 |
|
|---|
| 271 | void HelpWindow::pathSelected( const QString &_path )
|
|---|
| 272 | {
|
|---|
| 273 | browser->setSource( _path );
|
|---|
| 274 | if ( mHistory.values().contains(_path) )
|
|---|
| 275 | mHistory[ hist->insertItem( _path ) ] = _path;
|
|---|
| 276 | }
|
|---|
| 277 |
|
|---|
| 278 | void HelpWindow::readHistory()
|
|---|
| 279 | {
|
|---|
| 280 | if ( QFile::exists( QDir::currentDirPath() + "/.history" ) ) {
|
|---|
| 281 | QFile f( QDir::currentDirPath() + "/.history" );
|
|---|
| 282 | f.open( IO_ReadOnly );
|
|---|
| 283 | QDataStream s( &f );
|
|---|
| 284 | s >> history;
|
|---|
| 285 | f.close();
|
|---|
| 286 | while ( history.count() > 20 )
|
|---|
| 287 | history.remove( history.begin() );
|
|---|
| 288 | }
|
|---|
| 289 | }
|
|---|
| 290 |
|
|---|
| 291 | void HelpWindow::readBookmarks()
|
|---|
| 292 | {
|
|---|
| 293 | if ( QFile::exists( QDir::currentDirPath() + "/.bookmarks" ) ) {
|
|---|
| 294 | QFile f( QDir::currentDirPath() + "/.bookmarks" );
|
|---|
| 295 | f.open( IO_ReadOnly );
|
|---|
| 296 | QDataStream s( &f );
|
|---|
| 297 | s >> bookmarks;
|
|---|
| 298 | f.close();
|
|---|
| 299 | }
|
|---|
| 300 | }
|
|---|
| 301 |
|
|---|
| 302 | void HelpWindow::histChosen( int i )
|
|---|
| 303 | {
|
|---|
| 304 | if ( mHistory.contains( i ) )
|
|---|
| 305 | browser->setSource( mHistory[ i ] );
|
|---|
| 306 | }
|
|---|
| 307 |
|
|---|
| 308 | void HelpWindow::bookmChosen( int i )
|
|---|
| 309 | {
|
|---|
| 310 | if ( mBookmarks.contains( i ) )
|
|---|
| 311 | browser->setSource( mBookmarks[ i ] );
|
|---|
| 312 | }
|
|---|
| 313 |
|
|---|
| 314 | void HelpWindow::addBookmark()
|
|---|
| 315 | {
|
|---|
| 316 | mBookmarks[ bookm->insertItem( caption() ) ] = browser->context();
|
|---|
| 317 | }
|
|---|