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