| 1 | /****************************************************************************
|
|---|
| 2 | ** $Id: helpwindow.cpp 160 2006-12-11 20:15:57Z dmik $
|
|---|
| 3 | **
|
|---|
| 4 | ** Copyright (C) 1992-2000 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 ), selectedURL()
|
|---|
| 43 | {
|
|---|
| 44 | readHistory();
|
|---|
| 45 | readBookmarks();
|
|---|
| 46 |
|
|---|
| 47 | browser = new QTextBrowser( this );
|
|---|
| 48 | browser->mimeSourceFactory()->setFilePath( _path );
|
|---|
| 49 | browser->setFrameStyle( QFrame::Panel | QFrame::Sunken );
|
|---|
| 50 | connect( browser, SIGNAL( textChanged() ),
|
|---|
| 51 | this, SLOT( textChanged() ) );
|
|---|
| 52 |
|
|---|
| 53 | setCentralWidget( browser );
|
|---|
| 54 |
|
|---|
| 55 | if ( !home_.isEmpty() )
|
|---|
| 56 | browser->setSource( home_ );
|
|---|
| 57 |
|
|---|
| 58 | connect( browser, SIGNAL( highlighted( const QString&) ),
|
|---|
| 59 | statusBar(), SLOT( message( const QString&)) );
|
|---|
| 60 |
|
|---|
| 61 | resize( 640,700 );
|
|---|
| 62 |
|
|---|
| 63 | QPopupMenu* file = new QPopupMenu( this );
|
|---|
| 64 | file->insertItem( tr("&New Window"), this, SLOT( newWindow() ), ALT | Key_N );
|
|---|
| 65 | file->insertItem( tr("&Open File"), this, SLOT( openFile() ), ALT | Key_O );
|
|---|
| 66 | file->insertItem( tr("&Print"), this, SLOT( print() ), ALT | Key_P );
|
|---|
| 67 |
|
|---|
| 68 | // The same three icons are used twice each.
|
|---|
| 69 | QIconSet icon_back( QPixmap("textdrawing/previous.png") );
|
|---|
| 70 | QIconSet icon_forward( QPixmap("textdrawing/next.png") );
|
|---|
| 71 | QIconSet icon_home( QPixmap("textdrawing/home.png") );
|
|---|
| 72 |
|
|---|
| 73 | QPopupMenu* go = new QPopupMenu( this );
|
|---|
| 74 | backwardId = go->insertItem( icon_back,
|
|---|
| 75 | tr("&Backward"), browser, SLOT( backward() ),
|
|---|
| 76 | ALT | Key_Left );
|
|---|
| 77 | forwardId = go->insertItem( icon_forward,
|
|---|
| 78 | tr("&Forward"), browser, SLOT( forward() ),
|
|---|
| 79 | ALT | Key_Right );
|
|---|
| 80 | go->insertItem( icon_home, tr("&Home"), browser, SLOT( home() ) );
|
|---|
| 81 |
|
|---|
| 82 | hist = new QPopupMenu( this );
|
|---|
| 83 | QStringList::Iterator it = history.begin();
|
|---|
| 84 | for ( ; it != history.end(); ++it )
|
|---|
| 85 | mHistory[ hist->insertItem( *it ) ] = *it;
|
|---|
| 86 | connect( hist, SIGNAL( activated( int ) ),
|
|---|
| 87 | this, SLOT( histChosen( int ) ) );
|
|---|
| 88 |
|
|---|
| 89 | bookm = new QPopupMenu( this );
|
|---|
| 90 | bookm->insertItem( tr( "Add Bookmark" ), this, SLOT( addBookmark() ) );
|
|---|
| 91 | bookm->insertSeparator();
|
|---|
| 92 |
|
|---|
| 93 | QStringList::Iterator it2 = bookmarks.begin();
|
|---|
| 94 | for ( ; it2 != bookmarks.end(); ++it2 )
|
|---|
| 95 | mBookmarks[ bookm->insertItem( *it2 ) ] = *it2;
|
|---|
| 96 | connect( bookm, SIGNAL( activated( int ) ),
|
|---|
| 97 | this, SLOT( bookmChosen( int ) ) );
|
|---|
| 98 |
|
|---|
| 99 | menuBar()->insertItem( tr("&File"), file );
|
|---|
| 100 | menuBar()->insertItem( tr("&Go"), go );
|
|---|
| 101 | menuBar()->insertItem( tr( "History" ), hist );
|
|---|
| 102 | menuBar()->insertItem( tr( "Bookmarks" ), bookm );
|
|---|
| 103 |
|
|---|
| 104 | menuBar()->setItemEnabled( forwardId, FALSE);
|
|---|
| 105 | menuBar()->setItemEnabled( backwardId, FALSE);
|
|---|
| 106 | connect( browser, SIGNAL( backwardAvailable( bool ) ),
|
|---|
| 107 | this, SLOT( setBackwardAvailable( bool ) ) );
|
|---|
| 108 | connect( browser, SIGNAL( forwardAvailable( bool ) ),
|
|---|
| 109 | this, SLOT( setForwardAvailable( bool ) ) );
|
|---|
| 110 |
|
|---|
| 111 |
|
|---|
| 112 | QToolBar* toolbar = new QToolBar( this );
|
|---|
| 113 | addToolBar( toolbar, "Toolbar");
|
|---|
| 114 | QToolButton* button;
|
|---|
| 115 |
|
|---|
| 116 | button = new QToolButton( icon_back, tr("Backward"), "", browser, SLOT(backward()), toolbar );
|
|---|
| 117 | connect( browser, SIGNAL( backwardAvailable(bool) ), button, SLOT( setEnabled(bool) ) );
|
|---|
| 118 | button->setEnabled( FALSE );
|
|---|
| 119 | button = new QToolButton( icon_forward, tr("Forward"), "", browser, SLOT(forward()), toolbar );
|
|---|
| 120 | connect( browser, SIGNAL( forwardAvailable(bool) ), button, SLOT( setEnabled(bool) ) );
|
|---|
| 121 | button->setEnabled( FALSE );
|
|---|
| 122 | button = new QToolButton( icon_home, tr("Home"), "", browser, SLOT(home()), toolbar );
|
|---|
| 123 |
|
|---|
| 124 | toolbar->addSeparator();
|
|---|
| 125 |
|
|---|
| 126 | pathCombo = new QComboBox( TRUE, toolbar );
|
|---|
| 127 | connect( pathCombo, SIGNAL( activated( const QString & ) ),
|
|---|
| 128 | this, SLOT( pathSelected( const QString & ) ) );
|
|---|
| 129 | toolbar->setStretchableWidget( pathCombo );
|
|---|
| 130 | setRightJustification( TRUE );
|
|---|
| 131 | setDockEnabled( DockLeft, FALSE );
|
|---|
| 132 | setDockEnabled( DockRight, FALSE );
|
|---|
| 133 |
|
|---|
| 134 | pathCombo->insertItem( home_ );
|
|---|
| 135 |
|
|---|
| 136 | browser->setFocus();
|
|---|
| 137 | }
|
|---|
| 138 |
|
|---|
| 139 |
|
|---|
| 140 | void HelpWindow::setBackwardAvailable( bool b)
|
|---|
| 141 | {
|
|---|
| 142 | menuBar()->setItemEnabled( backwardId, b);
|
|---|
| 143 | }
|
|---|
| 144 |
|
|---|
| 145 | void HelpWindow::setForwardAvailable( bool b)
|
|---|
| 146 | {
|
|---|
| 147 | menuBar()->setItemEnabled( forwardId, b);
|
|---|
| 148 | }
|
|---|
| 149 |
|
|---|
| 150 |
|
|---|
| 151 | void HelpWindow::textChanged()
|
|---|
| 152 | {
|
|---|
| 153 | if ( browser->documentTitle().isNull() )
|
|---|
| 154 | setCaption( browser->context() );
|
|---|
| 155 | else
|
|---|
| 156 | setCaption( browser->documentTitle() ) ;
|
|---|
| 157 |
|
|---|
| 158 | selectedURL = caption();
|
|---|
| 159 | if ( !selectedURL.isEmpty() && pathCombo ) {
|
|---|
| 160 | bool exists = FALSE;
|
|---|
| 161 | int i;
|
|---|
| 162 | for ( i = 0; i < pathCombo->count(); ++i ) {
|
|---|
| 163 | if ( pathCombo->text( i ) == selectedURL ) {
|
|---|
| 164 | exists = TRUE;
|
|---|
| 165 | break;
|
|---|
| 166 | }
|
|---|
| 167 | }
|
|---|
| 168 | if ( !exists ) {
|
|---|
| 169 | pathCombo->insertItem( selectedURL, 0 );
|
|---|
| 170 | pathCombo->setCurrentItem( 0 );
|
|---|
| 171 | mHistory[ hist->insertItem( selectedURL ) ] = selectedURL;
|
|---|
| 172 | } else
|
|---|
| 173 | pathCombo->setCurrentItem( i );
|
|---|
| 174 | selectedURL = QString::null;
|
|---|
| 175 | }
|
|---|
| 176 | }
|
|---|
| 177 |
|
|---|
| 178 | HelpWindow::~HelpWindow()
|
|---|
| 179 | {
|
|---|
| 180 | history.clear();
|
|---|
| 181 | QMap<int, QString>::Iterator it = mHistory.begin();
|
|---|
| 182 | for ( ; it != mHistory.end(); ++it )
|
|---|
| 183 | history.append( *it );
|
|---|
| 184 |
|
|---|
| 185 | QFile f( QDir::currentDirPath() + "/.history" );
|
|---|
| 186 | f.open( IO_WriteOnly );
|
|---|
| 187 | QDataStream s( &f );
|
|---|
| 188 | s << history;
|
|---|
| 189 | f.close();
|
|---|
| 190 |
|
|---|
| 191 | bookmarks.clear();
|
|---|
| 192 | QMap<int, QString>::Iterator it2 = mBookmarks.begin();
|
|---|
| 193 | for ( ; it2 != mBookmarks.end(); ++it2 )
|
|---|
| 194 | bookmarks.append( *it2 );
|
|---|
| 195 |
|
|---|
| 196 | QFile f2( QDir::currentDirPath() + "/.bookmarks" );
|
|---|
| 197 | f2.open( IO_WriteOnly );
|
|---|
| 198 | QDataStream s2( &f2 );
|
|---|
| 199 | s2 << bookmarks;
|
|---|
| 200 | f2.close();
|
|---|
| 201 | }
|
|---|
| 202 |
|
|---|
| 203 | void HelpWindow::about()
|
|---|
| 204 | {
|
|---|
| 205 | QMessageBox::about( this, "HelpViewer Example",
|
|---|
| 206 | "<p>This example implements a simple HTML help viewer "
|
|---|
| 207 | "using Qt's rich text capabilities</p>"
|
|---|
| 208 | "<p>It's just about 100 lines of C++ code, so don't expect too much :-)</p>"
|
|---|
| 209 | );
|
|---|
| 210 | }
|
|---|
| 211 |
|
|---|
| 212 |
|
|---|
| 213 | void HelpWindow::aboutQt()
|
|---|
| 214 | {
|
|---|
| 215 | QMessageBox::aboutQt( this, "QBrowser" );
|
|---|
| 216 | }
|
|---|
| 217 |
|
|---|
| 218 | void HelpWindow::openFile()
|
|---|
| 219 | {
|
|---|
| 220 | #ifndef QT_NO_FILEDIALOG
|
|---|
| 221 | QString fn = QFileDialog::getOpenFileName( QString::null, QString::null, this );
|
|---|
| 222 | if ( !fn.isEmpty() )
|
|---|
| 223 | browser->setSource( fn );
|
|---|
| 224 | #endif
|
|---|
| 225 | }
|
|---|
| 226 |
|
|---|
| 227 | void HelpWindow::newWindow()
|
|---|
| 228 | {
|
|---|
| 229 | ( new HelpWindow(browser->source(), "qbrowser") )->show();
|
|---|
| 230 | }
|
|---|
| 231 |
|
|---|
| 232 | void HelpWindow::print()
|
|---|
| 233 | {
|
|---|
| 234 | #ifndef QT_NO_PRINTER
|
|---|
| 235 | QPrinter printer;
|
|---|
| 236 | printer.setFullPage(TRUE);
|
|---|
| 237 | if ( printer.setup() ) {
|
|---|
| 238 | QPainter p( &printer );
|
|---|
| 239 | QPaintDeviceMetrics metrics(p.device());
|
|---|
| 240 | int dpix = metrics.logicalDpiX();
|
|---|
| 241 | int dpiy = metrics.logicalDpiY();
|
|---|
| 242 | const int margin = 72; // pt
|
|---|
| 243 | QRect body(margin*dpix/72, margin*dpiy/72,
|
|---|
| 244 | metrics.width()-margin*dpix/72*2,
|
|---|
| 245 | metrics.height()-margin*dpiy/72*2 );
|
|---|
| 246 | QFont font("times", 10);
|
|---|
| 247 | QStringList filePaths = browser->mimeSourceFactory()->filePath();
|
|---|
| 248 | QString file;
|
|---|
| 249 | QStringList::Iterator it = filePaths.begin();
|
|---|
| 250 | for ( ; it != filePaths.end(); ++it ) {
|
|---|
| 251 | file = QUrl( *it, QUrl( browser->source() ).path() ).path();
|
|---|
| 252 | if ( QFile::exists( file ) )
|
|---|
| 253 | break;
|
|---|
| 254 | else
|
|---|
| 255 | file = QString::null;
|
|---|
| 256 | }
|
|---|
| 257 | if ( file.isEmpty() )
|
|---|
| 258 | return;
|
|---|
| 259 | QFile f( file );
|
|---|
| 260 | if ( !f.open( IO_ReadOnly ) )
|
|---|
| 261 | return;
|
|---|
| 262 | QTextStream ts( &f );
|
|---|
| 263 | QSimpleRichText richText( ts.read(), font, browser->context(), browser->styleSheet(),
|
|---|
| 264 | browser->mimeSourceFactory(), body.height() );
|
|---|
| 265 | richText.setWidth( &p, body.width() );
|
|---|
| 266 | QRect view( body );
|
|---|
| 267 | int page = 1;
|
|---|
| 268 | do {
|
|---|
| 269 | richText.draw( &p, body.left(), body.top(), view, colorGroup() );
|
|---|
| 270 | view.moveBy( 0, body.height() );
|
|---|
| 271 | p.translate( 0 , -body.height() );
|
|---|
| 272 | p.setFont( font );
|
|---|
| 273 | p.drawText( view.right() - p.fontMetrics().width( QString::number(page) ),
|
|---|
| 274 | view.bottom() + p.fontMetrics().ascent() + 5, QString::number(page) );
|
|---|
| 275 | if ( view.top() >= richText.height() )
|
|---|
| 276 | break;
|
|---|
| 277 | printer.newPage();
|
|---|
| 278 | page++;
|
|---|
| 279 | } while (TRUE);
|
|---|
| 280 | }
|
|---|
| 281 | #endif
|
|---|
| 282 | }
|
|---|
| 283 |
|
|---|
| 284 | void HelpWindow::pathSelected( const QString &_path )
|
|---|
| 285 | {
|
|---|
| 286 | browser->setSource( _path );
|
|---|
| 287 | QMap<int, QString>::Iterator it = mHistory.begin();
|
|---|
| 288 | bool exists = FALSE;
|
|---|
| 289 | for ( ; it != mHistory.end(); ++it ) {
|
|---|
| 290 | if ( *it == _path ) {
|
|---|
| 291 | exists = TRUE;
|
|---|
| 292 | break;
|
|---|
| 293 | }
|
|---|
| 294 | }
|
|---|
| 295 | if ( !exists )
|
|---|
| 296 | mHistory[ hist->insertItem( _path ) ] = _path;
|
|---|
| 297 | }
|
|---|
| 298 |
|
|---|
| 299 | void HelpWindow::readHistory()
|
|---|
| 300 | {
|
|---|
| 301 | if ( QFile::exists( QDir::currentDirPath() + "/.history" ) ) {
|
|---|
| 302 | QFile f( QDir::currentDirPath() + "/.history" );
|
|---|
| 303 | f.open( IO_ReadOnly );
|
|---|
| 304 | QDataStream s( &f );
|
|---|
| 305 | s >> history;
|
|---|
| 306 | f.close();
|
|---|
| 307 | while ( history.count() > 20 )
|
|---|
| 308 | history.remove( history.begin() );
|
|---|
| 309 | }
|
|---|
| 310 | }
|
|---|
| 311 |
|
|---|
| 312 | void HelpWindow::readBookmarks()
|
|---|
| 313 | {
|
|---|
| 314 | if ( QFile::exists( QDir::currentDirPath() + "/.bookmarks" ) ) {
|
|---|
| 315 | QFile f( QDir::currentDirPath() + "/.bookmarks" );
|
|---|
| 316 | f.open( IO_ReadOnly );
|
|---|
| 317 | QDataStream s( &f );
|
|---|
| 318 | s >> bookmarks;
|
|---|
| 319 | f.close();
|
|---|
| 320 | }
|
|---|
| 321 | }
|
|---|
| 322 |
|
|---|
| 323 | void HelpWindow::histChosen( int i )
|
|---|
| 324 | {
|
|---|
| 325 | if ( mHistory.contains( i ) )
|
|---|
| 326 | browser->setSource( mHistory[ i ] );
|
|---|
| 327 | }
|
|---|
| 328 |
|
|---|
| 329 | void HelpWindow::bookmChosen( int i )
|
|---|
| 330 | {
|
|---|
| 331 | if ( mBookmarks.contains( i ) )
|
|---|
| 332 | browser->setSource( mBookmarks[ i ] );
|
|---|
| 333 | }
|
|---|
| 334 |
|
|---|
| 335 | void HelpWindow::addBookmark()
|
|---|
| 336 | {
|
|---|
| 337 | mBookmarks[ bookm->insertItem( caption() ) ] = caption();
|
|---|
| 338 | }
|
|---|