[2] | 1 | /****************************************************************************
|
---|
| 2 | ** $Id: application.cpp 20 2005-11-17 18:00:27Z 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 "application.h"
|
---|
| 12 | #include <qworkspace.h>
|
---|
| 13 | #include <qimage.h>
|
---|
| 14 | #include <qpixmap.h>
|
---|
| 15 | #include <qtoolbar.h>
|
---|
| 16 | #include <qtoolbutton.h>
|
---|
| 17 | #include <qpopupmenu.h>
|
---|
| 18 | #include <qmenubar.h>
|
---|
| 19 | #include <qmovie.h>
|
---|
| 20 | #include <qfile.h>
|
---|
| 21 | #include <qfiledialog.h>
|
---|
| 22 | #include <qlabel.h>
|
---|
| 23 | #include <qstatusbar.h>
|
---|
| 24 | #include <qmessagebox.h>
|
---|
| 25 | #include <qprinter.h>
|
---|
| 26 | #include <qapplication.h>
|
---|
| 27 | #include <qpushbutton.h>
|
---|
| 28 | #include <qaccel.h>
|
---|
| 29 | #include <qtextstream.h>
|
---|
| 30 | #include <qtextedit.h>
|
---|
| 31 | #include <qpainter.h>
|
---|
| 32 | #include <qpaintdevicemetrics.h>
|
---|
| 33 | #include <qwhatsthis.h>
|
---|
| 34 | #include <qobjectlist.h>
|
---|
| 35 | #include <qvbox.h>
|
---|
| 36 | #include <qsimplerichtext.h>
|
---|
| 37 |
|
---|
| 38 | #include "filesave.xpm"
|
---|
| 39 | #include "fileopen.xpm"
|
---|
[20] | 40 | #ifndef QT_NO_PRINTER
|
---|
[2] | 41 | #include "fileprint.xpm"
|
---|
[20] | 42 | #endif
|
---|
[2] | 43 |
|
---|
| 44 | const char * fileOpenText = "Click this button to open a <em>new file</em>. <br><br>"
|
---|
| 45 | "You can also select the <b>Open command</b> from the File menu.";
|
---|
| 46 | const char * fileSaveText = "Click this button to save the file you are "
|
---|
| 47 | "editing. You will be prompted for a file name.\n\n"
|
---|
| 48 | "You can also select the Save command from the File menu.\n\n"
|
---|
| 49 | "Note that implementing this function is left as an exercise for the reader.";
|
---|
| 50 | const char * filePrintText = "Click this button to print the file you "
|
---|
| 51 | "are editing.\n\n"
|
---|
| 52 | "You can also select the Print command from the File menu.";
|
---|
| 53 |
|
---|
| 54 | ApplicationWindow::ApplicationWindow()
|
---|
| 55 | : QMainWindow( 0, "example application main window", WDestructiveClose )
|
---|
| 56 | {
|
---|
| 57 | int id;
|
---|
| 58 |
|
---|
| 59 | QPixmap openIcon, saveIcon;
|
---|
| 60 |
|
---|
| 61 | fileTools = new QToolBar( this, "file operations" );
|
---|
| 62 | addToolBar( fileTools, tr( "File Operations" ), DockTop, TRUE );
|
---|
| 63 |
|
---|
| 64 | openIcon = QPixmap( fileopen );
|
---|
| 65 | QToolButton * fileOpen
|
---|
| 66 | = new QToolButton( openIcon, "Open File", QString::null,
|
---|
| 67 | this, SLOT(load()), fileTools, "open file" );
|
---|
| 68 |
|
---|
| 69 | saveIcon = QPixmap( filesave );
|
---|
| 70 | QToolButton * fileSave
|
---|
| 71 | = new QToolButton( saveIcon, "Save File", QString::null,
|
---|
| 72 | this, SLOT(save()), fileTools, "save file" );
|
---|
| 73 |
|
---|
| 74 | #ifndef QT_NO_PRINTER
|
---|
| 75 | printer = new QPrinter( QPrinter::HighResolution );
|
---|
| 76 | QPixmap printIcon;
|
---|
| 77 |
|
---|
| 78 | printIcon = QPixmap( fileprint );
|
---|
| 79 | QToolButton * filePrint
|
---|
| 80 | = new QToolButton( printIcon, "Print File", QString::null,
|
---|
| 81 | this, SLOT(print()), fileTools, "print file" );
|
---|
| 82 | QWhatsThis::add( filePrint, filePrintText );
|
---|
| 83 | #endif
|
---|
| 84 |
|
---|
| 85 | (void)QWhatsThis::whatsThisButton( fileTools );
|
---|
| 86 |
|
---|
| 87 | QWhatsThis::add( fileOpen, fileOpenText );
|
---|
| 88 | QWhatsThis::add( fileSave, fileSaveText );
|
---|
| 89 |
|
---|
| 90 | QPopupMenu * file = new QPopupMenu( this );
|
---|
| 91 | menuBar()->insertItem( "&File", file );
|
---|
| 92 |
|
---|
| 93 | file->insertItem( "&New", this, SLOT(newDoc()), CTRL+Key_N );
|
---|
| 94 |
|
---|
| 95 | id = file->insertItem( openIcon, "&Open...",
|
---|
| 96 | this, SLOT(load()), CTRL+Key_O );
|
---|
| 97 | file->setWhatsThis( id, fileOpenText );
|
---|
| 98 |
|
---|
| 99 | id = file->insertItem( saveIcon, "&Save",
|
---|
| 100 | this, SLOT(save()), CTRL+Key_S );
|
---|
| 101 | file->setWhatsThis( id, fileSaveText );
|
---|
| 102 | id = file->insertItem( "Save &As...", this, SLOT(saveAs()) );
|
---|
| 103 | file->setWhatsThis( id, fileSaveText );
|
---|
| 104 | #ifndef QT_NO_PRINTER
|
---|
| 105 | file->insertSeparator();
|
---|
| 106 | id = file->insertItem( printIcon, "&Print...",
|
---|
| 107 | this, SLOT(print()), CTRL+Key_P );
|
---|
| 108 | file->setWhatsThis( id, filePrintText );
|
---|
| 109 | #endif
|
---|
| 110 | file->insertSeparator();
|
---|
| 111 | file->insertItem( "&Close", this, SLOT(closeWindow()), CTRL+Key_W );
|
---|
| 112 | file->insertItem( "&Quit", qApp, SLOT( closeAllWindows() ), CTRL+Key_Q );
|
---|
| 113 |
|
---|
| 114 | windowsMenu = new QPopupMenu( this );
|
---|
| 115 | windowsMenu->setCheckable( TRUE );
|
---|
| 116 | connect( windowsMenu, SIGNAL( aboutToShow() ),
|
---|
| 117 | this, SLOT( windowsMenuAboutToShow() ) );
|
---|
| 118 | menuBar()->insertItem( "&Windows", windowsMenu );
|
---|
| 119 |
|
---|
| 120 | menuBar()->insertSeparator();
|
---|
| 121 | QPopupMenu * help = new QPopupMenu( this );
|
---|
| 122 | menuBar()->insertItem( "&Help", help );
|
---|
| 123 |
|
---|
| 124 | help->insertItem( "&About", this, SLOT(about()), Key_F1);
|
---|
| 125 | help->insertItem( "About &Qt", this, SLOT(aboutQt()));
|
---|
| 126 | help->insertSeparator();
|
---|
| 127 | help->insertItem( "What's &This", this, SLOT(whatsThis()), SHIFT+Key_F1);
|
---|
| 128 |
|
---|
| 129 | QVBox* vb = new QVBox( this );
|
---|
| 130 | vb->setFrameStyle( QFrame::StyledPanel | QFrame::Sunken );
|
---|
| 131 | ws = new QWorkspace( vb );
|
---|
| 132 | ws->setScrollBarsEnabled( TRUE );
|
---|
| 133 | setCentralWidget( vb );
|
---|
| 134 |
|
---|
| 135 | statusBar()->message( "Ready", 2000 );
|
---|
| 136 | }
|
---|
| 137 |
|
---|
| 138 |
|
---|
| 139 | ApplicationWindow::~ApplicationWindow()
|
---|
| 140 | {
|
---|
| 141 | #ifndef QT_NO_PRINTER
|
---|
| 142 | delete printer;
|
---|
| 143 | #endif
|
---|
| 144 | }
|
---|
| 145 |
|
---|
| 146 |
|
---|
| 147 |
|
---|
| 148 | MDIWindow* ApplicationWindow::newDoc()
|
---|
| 149 | {
|
---|
| 150 | MDIWindow* w = new MDIWindow( ws, 0, WDestructiveClose );
|
---|
| 151 | connect( w, SIGNAL( message(const QString&, int) ), statusBar(), SLOT( message(const QString&, int )) );
|
---|
| 152 | w->setCaption("unnamed document");
|
---|
| 153 | w->setIcon( QPixmap("document.xpm") );
|
---|
| 154 | // show the very first window in maximized mode
|
---|
| 155 | if ( ws->windowList().isEmpty() )
|
---|
| 156 | w->showMaximized();
|
---|
| 157 | else
|
---|
| 158 | w->show();
|
---|
| 159 | return w;
|
---|
| 160 | }
|
---|
| 161 |
|
---|
| 162 | void ApplicationWindow::load()
|
---|
| 163 | {
|
---|
| 164 | QString fn = QFileDialog::getOpenFileName( QString::null, QString::null, this );
|
---|
| 165 | if ( !fn.isEmpty() ) {
|
---|
| 166 | MDIWindow* w = newDoc();
|
---|
| 167 | w->load( fn );
|
---|
| 168 | } else {
|
---|
| 169 | statusBar()->message( "Loading aborted", 2000 );
|
---|
| 170 | }
|
---|
| 171 | }
|
---|
| 172 |
|
---|
| 173 | void ApplicationWindow::save()
|
---|
| 174 | {
|
---|
| 175 | MDIWindow* m = (MDIWindow*)ws->activeWindow();
|
---|
| 176 | if ( m )
|
---|
| 177 | m->save();
|
---|
| 178 | }
|
---|
| 179 |
|
---|
| 180 |
|
---|
| 181 | void ApplicationWindow::saveAs()
|
---|
| 182 | {
|
---|
| 183 | MDIWindow* m = (MDIWindow*)ws->activeWindow();
|
---|
| 184 | if ( m )
|
---|
| 185 | m->saveAs();
|
---|
| 186 | }
|
---|
| 187 |
|
---|
| 188 |
|
---|
| 189 | void ApplicationWindow::print()
|
---|
| 190 | {
|
---|
| 191 | #ifndef QT_NO_PRINTER
|
---|
| 192 | MDIWindow* m = (MDIWindow*)ws->activeWindow();
|
---|
| 193 | if ( m )
|
---|
| 194 | m->print( printer );
|
---|
| 195 | #endif
|
---|
| 196 | }
|
---|
| 197 |
|
---|
| 198 |
|
---|
| 199 | void ApplicationWindow::closeWindow()
|
---|
| 200 | {
|
---|
| 201 | MDIWindow* m = (MDIWindow*)ws->activeWindow();
|
---|
| 202 | if ( m )
|
---|
| 203 | m->close();
|
---|
| 204 | }
|
---|
| 205 |
|
---|
| 206 | void ApplicationWindow::about()
|
---|
| 207 | {
|
---|
| 208 | QMessageBox::about( this, "Qt Application Example",
|
---|
| 209 | "This example demonstrates simple use of\n "
|
---|
| 210 | "Qt's Multiple Document Interface (MDI).");
|
---|
| 211 | }
|
---|
| 212 |
|
---|
| 213 |
|
---|
| 214 | void ApplicationWindow::aboutQt()
|
---|
| 215 | {
|
---|
| 216 | QMessageBox::aboutQt( this, "Qt Application Example" );
|
---|
| 217 | }
|
---|
| 218 |
|
---|
| 219 |
|
---|
| 220 | void ApplicationWindow::windowsMenuAboutToShow()
|
---|
| 221 | {
|
---|
| 222 | windowsMenu->clear();
|
---|
| 223 | int cascadeId = windowsMenu->insertItem("&Cascade", ws, SLOT(cascade() ) );
|
---|
| 224 | int tileId = windowsMenu->insertItem("&Tile", ws, SLOT(tile() ) );
|
---|
| 225 | int horTileId = windowsMenu->insertItem("Tile &Horizontally", this, SLOT(tileHorizontal() ) );
|
---|
| 226 | if ( ws->windowList().isEmpty() ) {
|
---|
| 227 | windowsMenu->setItemEnabled( cascadeId, FALSE );
|
---|
| 228 | windowsMenu->setItemEnabled( tileId, FALSE );
|
---|
| 229 | windowsMenu->setItemEnabled( horTileId, FALSE );
|
---|
| 230 | }
|
---|
| 231 | windowsMenu->insertSeparator();
|
---|
| 232 | QWidgetList windows = ws->windowList();
|
---|
| 233 | for ( int i = 0; i < int(windows.count()); ++i ) {
|
---|
| 234 | int id = windowsMenu->insertItem(windows.at(i)->caption(),
|
---|
| 235 | this, SLOT( windowsMenuActivated( int ) ) );
|
---|
| 236 | windowsMenu->setItemParameter( id, i );
|
---|
| 237 | windowsMenu->setItemChecked( id, ws->activeWindow() == windows.at(i) );
|
---|
| 238 | }
|
---|
| 239 | }
|
---|
| 240 |
|
---|
| 241 | void ApplicationWindow::windowsMenuActivated( int id )
|
---|
| 242 | {
|
---|
| 243 | QWidget* w = ws->windowList().at( id );
|
---|
| 244 | if ( w )
|
---|
| 245 | w->showNormal();
|
---|
| 246 | w->setFocus();
|
---|
| 247 | }
|
---|
| 248 |
|
---|
| 249 | void ApplicationWindow::tileHorizontal()
|
---|
| 250 | {
|
---|
| 251 | // primitive horizontal tiling
|
---|
| 252 | QWidgetList windows = ws->windowList();
|
---|
| 253 | if ( !windows.count() )
|
---|
| 254 | return;
|
---|
| 255 |
|
---|
| 256 | int heightForEach = ws->height() / windows.count();
|
---|
| 257 | int y = 0;
|
---|
| 258 | for ( int i = 0; i < int(windows.count()); ++i ) {
|
---|
| 259 | QWidget *window = windows.at(i);
|
---|
| 260 | if ( window->testWState( WState_Maximized ) ) {
|
---|
| 261 | // prevent flicker
|
---|
| 262 | window->hide();
|
---|
| 263 | window->showNormal();
|
---|
| 264 | }
|
---|
| 265 | int preferredHeight = window->minimumHeight()+window->parentWidget()->baseSize().height();
|
---|
| 266 | int actHeight = QMAX(heightForEach, preferredHeight);
|
---|
| 267 |
|
---|
| 268 | window->parentWidget()->setGeometry( 0, y, ws->width(), actHeight );
|
---|
| 269 | y += actHeight;
|
---|
| 270 | }
|
---|
| 271 | }
|
---|
| 272 |
|
---|
| 273 | void ApplicationWindow::closeEvent( QCloseEvent *e )
|
---|
| 274 | {
|
---|
| 275 | QWidgetList windows = ws->windowList();
|
---|
| 276 | if ( windows.count() ) {
|
---|
| 277 | for ( int i = 0; i < int(windows.count()); ++i ) {
|
---|
| 278 | QWidget *window = windows.at( i );
|
---|
| 279 | if ( !window->close() ) {
|
---|
| 280 | e->ignore();
|
---|
| 281 | return;
|
---|
| 282 | }
|
---|
| 283 | }
|
---|
| 284 | }
|
---|
| 285 |
|
---|
| 286 | QMainWindow::closeEvent( e );
|
---|
| 287 | }
|
---|
| 288 |
|
---|
| 289 | MDIWindow::MDIWindow( QWidget* parent, const char* name, int wflags )
|
---|
| 290 | : QMainWindow( parent, name, wflags )
|
---|
| 291 | {
|
---|
| 292 | mmovie = 0;
|
---|
| 293 | medit = new QTextEdit( this );
|
---|
| 294 | setFocusProxy( medit );
|
---|
| 295 | setCentralWidget( medit );
|
---|
| 296 | }
|
---|
| 297 |
|
---|
| 298 | MDIWindow::~MDIWindow()
|
---|
| 299 | {
|
---|
| 300 | delete mmovie;
|
---|
| 301 | }
|
---|
| 302 |
|
---|
| 303 | void MDIWindow::closeEvent( QCloseEvent *e )
|
---|
| 304 | {
|
---|
| 305 | if ( medit->isModified() ) {
|
---|
| 306 | switch( QMessageBox::warning( this, "Save Changes",
|
---|
| 307 | tr("Save changes to %1?").arg( caption() ),
|
---|
| 308 | tr("Yes"), tr("No"), tr("Cancel") ) ) {
|
---|
| 309 | case 0:
|
---|
| 310 | {
|
---|
| 311 | save();
|
---|
| 312 | if ( !filename.isEmpty() )
|
---|
| 313 | e->accept();
|
---|
| 314 | else
|
---|
| 315 | e->ignore();
|
---|
| 316 | }
|
---|
| 317 | break;
|
---|
| 318 | case 1:
|
---|
| 319 | e->accept();
|
---|
| 320 | break;
|
---|
| 321 | default:
|
---|
| 322 | e->ignore();
|
---|
| 323 | break;
|
---|
| 324 | }
|
---|
| 325 | } else {
|
---|
| 326 | e->accept();
|
---|
| 327 | }
|
---|
| 328 | }
|
---|
| 329 |
|
---|
| 330 | void MDIWindow::load( const QString& fn )
|
---|
| 331 | {
|
---|
| 332 | filename = fn;
|
---|
| 333 | QFile f( filename );
|
---|
| 334 | if ( !f.open( IO_ReadOnly ) )
|
---|
| 335 | return;
|
---|
| 336 |
|
---|
| 337 | if(fn.contains(".gif")) {
|
---|
| 338 | QWidget * tmp=new QWidget(this);
|
---|
| 339 | setFocusProxy(tmp);
|
---|
| 340 | setCentralWidget(tmp);
|
---|
| 341 | medit->hide();
|
---|
| 342 | delete medit;
|
---|
| 343 | QMovie * qm=new QMovie(fn);
|
---|
| 344 | #ifdef Q_WS_QWS // temporary speed-test hack
|
---|
| 345 | qm->setDisplayWidget(tmp);
|
---|
| 346 | #endif
|
---|
| 347 | tmp->setBackgroundMode(QWidget::NoBackground);
|
---|
| 348 | tmp->show();
|
---|
| 349 | mmovie=qm;
|
---|
| 350 | } else {
|
---|
| 351 | mmovie = 0;
|
---|
| 352 |
|
---|
| 353 | QTextStream t(&f);
|
---|
| 354 | QString s = t.read();
|
---|
| 355 | medit->setText( s );
|
---|
| 356 | f.close();
|
---|
| 357 |
|
---|
| 358 |
|
---|
| 359 | }
|
---|
| 360 | setCaption( filename );
|
---|
| 361 | emit message( QString("Loaded document %1").arg(filename), 2000 );
|
---|
| 362 | }
|
---|
| 363 |
|
---|
| 364 | void MDIWindow::save()
|
---|
| 365 | {
|
---|
| 366 | if ( filename.isEmpty() ) {
|
---|
| 367 | saveAs();
|
---|
| 368 | return;
|
---|
| 369 | }
|
---|
| 370 |
|
---|
| 371 | QString text = medit->text();
|
---|
| 372 | QFile f( filename );
|
---|
| 373 | if ( !f.open( IO_WriteOnly ) ) {
|
---|
| 374 | emit message( QString("Could not write to %1").arg(filename),
|
---|
| 375 | 2000 );
|
---|
| 376 | return;
|
---|
| 377 | }
|
---|
| 378 |
|
---|
| 379 | QTextStream t( &f );
|
---|
| 380 | t << text;
|
---|
| 381 | f.close();
|
---|
| 382 |
|
---|
| 383 | setCaption( filename );
|
---|
| 384 |
|
---|
| 385 | emit message( QString( "File %1 saved" ).arg( filename ), 2000 );
|
---|
| 386 | }
|
---|
| 387 |
|
---|
| 388 | void MDIWindow::saveAs()
|
---|
| 389 | {
|
---|
| 390 | QString fn = QFileDialog::getSaveFileName( filename, QString::null, this );
|
---|
| 391 | if ( !fn.isEmpty() ) {
|
---|
| 392 | filename = fn;
|
---|
| 393 | save();
|
---|
| 394 | } else {
|
---|
| 395 | emit message( "Saving aborted", 2000 );
|
---|
| 396 | }
|
---|
| 397 | }
|
---|
| 398 |
|
---|
| 399 | void MDIWindow::print( QPrinter* printer)
|
---|
| 400 | {
|
---|
| 401 | #ifndef QT_NO_PRINTER
|
---|
| 402 | int pageNo = 1;
|
---|
| 403 |
|
---|
| 404 | if ( printer->setup(this) ) { // printer dialog
|
---|
| 405 | printer->setFullPage( TRUE );
|
---|
| 406 | emit message( "Printing...", 0 );
|
---|
| 407 | QPainter p;
|
---|
| 408 | if ( !p.begin( printer ) )
|
---|
| 409 | return; // paint on printer
|
---|
| 410 | QPaintDeviceMetrics metrics( p.device() );
|
---|
| 411 | int dpiy = metrics.logicalDpiY();
|
---|
| 412 | int margin = (int) ( (2/2.54)*dpiy ); // 2 cm margins
|
---|
| 413 | QRect body( margin, margin, metrics.width() - 2*margin, metrics.height() - 2*margin );
|
---|
| 414 | QSimpleRichText richText( QStyleSheet::convertFromPlainText(medit->text()),
|
---|
| 415 | QFont(),
|
---|
| 416 | medit->context(),
|
---|
| 417 | medit->styleSheet(),
|
---|
| 418 | medit->mimeSourceFactory(),
|
---|
| 419 | body.height() );
|
---|
| 420 | richText.setWidth( &p, body.width() );
|
---|
| 421 | QRect view( body );
|
---|
| 422 | int page = 1;
|
---|
| 423 | do {
|
---|
| 424 | richText.draw( &p, body.left(), body.top(), view, colorGroup() );
|
---|
| 425 | view.moveBy( 0, body.height() );
|
---|
| 426 | p.translate( 0 , -body.height() );
|
---|
| 427 | p.drawText( view.right() - p.fontMetrics().width( QString::number( page ) ),
|
---|
| 428 | view.bottom() + p.fontMetrics().ascent() + 5, QString::number( page ) );
|
---|
| 429 | if ( view.top() >= richText.height() )
|
---|
| 430 | break;
|
---|
| 431 | QString msg( "Printing (page " );
|
---|
| 432 | msg += QString::number( ++pageNo );
|
---|
| 433 | msg += ")...";
|
---|
| 434 | emit message( msg, 0 );
|
---|
| 435 | printer->newPage();
|
---|
| 436 | page++;
|
---|
| 437 | } while (TRUE);
|
---|
| 438 | }
|
---|
| 439 | #endif
|
---|
| 440 | }
|
---|