package ApplicationWindow; use Qt 2.0; import Qt::app; use Qt::slots ( 'newDoc()', 'load()', 'loadFile(cstring)', 'save()', 'print()', 'closeDoc()', 'toggleMenuBar()', 'toggleStatusBar()', 'toggleToolBar()' ); @ISA = qw(Qt::MainWindow); sub readxpm { my $xpm = shift; open(XPM, $xpm) || return []; $str = join('', ); close(XPM); $str =~ s/^.*\{(.*)\}.*/\@xpm = ($1)/s; my @xpm; eval "$str"; return \@xpm; } $fileopen = readxpm("fileopen.xpm"); $filesave = readxpm("filesave.xpm"); $fileprint = readxpm("fileprint.xpm"); my $fileOpenText = "Click this button to open a new file.\n\n" . "You can also select the Open command from the File menu."; my $fileSaveText = "Click this button to save the file you are " . "editing. You will be prompted for a file name.\n\n" . "You can also select the Save command from the File menu.\n\n" . "Note that implementing this function is left as an exercise for the reader."; my $filePrintText = "Click this button to print the file you " . "are editing.\n\n" . "You can also select the Print command from the File menu."; sub new { my $self = shift->SUPER::new(undef, "example application main window"); my $printer = $self->{'printer'} = Qt::Printer->new; $printer->setMinMax(1, 10); my $fileTools = $self->{'fileTools'} = Qt::ToolBar->new($self, 'file operations'); my $openIcon = $self->{'openIcon'} = Qt::Pixmap->new($fileopen); my $fileOpen = Qt::ToolButton->new($openIcon, "Open File", undef, $self, 'load()', $fileTools, "open file"); my $saveIcon = $self->{'saveIcon'} = Qt::Pixmap->new($filesave); my $fileSave = Qt::ToolButton->new($saveIcon, "Save File", undef, $self, 'save()', $fileTools, "save file"); my $printIcon = $self->{'printIcon'} = Qt::Pixmap->new($fileprint); my $filePrint = Qt::ToolButton->new($printIcon, "Print File", undef, $self, 'print()', $fileTools, "print file"); Qt::WhatsThis::whatsThisButton($fileTools); Qt::WhatsThis::add($fileOpen, $fileOpenText, 0); Qt::WhatsThis::add($fileSave, $fileSaveText, 0); Qt::WhatsThis::add($filePrint, $filePrintText, 0); my $file = Qt::PopupMenu->new; $self->menuBar()->insertItem('&File', $file); $file->insertItem("New", $self, 'newDoc()', Qt::CTRL+Qt::Key_N); $file->insertItem($openIcon, "Open", $self, 'load()', Qt::CTRL+Qt::Key_O); $file->insertItem($saveIcon, "Save", $self, 'save()', Qt::CTRL+Qt::Key_S); $file->insertSeparator(); $file->insertItem($printIcon, "Print", $self, 'print()', Qt::CTRL+Qt::Key_P); $file->insertSeparator(); $file->insertItem("Close", $self, 'closeDoc()', Qt::CTRL+Qt::Key_W); $file->insertItem("Quit", $app, 'quit()', Qt::CTRL+Qt::Key_Q); my $controls = $self->{'controls'} = Qt::PopupMenu->new; $self->menuBar()->insertItem("&Controls", $controls); my $mb = $self->{'mb'} = $controls->insertItem("Menu bar", $self, 'toggleMenuBar()', Qt::CTRL+Qt::Key_M); # Now an accelerator for when the menubar is invisible! my $a = Qt::Accel->new($self); $a->connectItem($a->insertItem(Qt::CTRL+Qt::Key_M), $self, 'toggleMenuBar()'); my $tb = $self->{'tb'} = $controls->insertItem("Tool bar", $self, 'toggleToolBar()', Qt::CTRL+Qt::Key_T); my $sb = $self->{'sb'} = $controls->insertItem("Status bar", $self, 'toggleStatusBar()', Qt::CTRL+Qt::Key_B); $controls->setCheckable(1); $controls->setItemChecked($mb, 1); $controls->setItemChecked($tb, 1); $controls->setItemChecked($sb, 1); my $e = $self->{'e'} = Qt::MultiLineEdit->new($self, "editor"); $e->setFocus(); $self->setCentralWidget($e); $self->statusBar()->message("Ready", 2000); return $self; } # No destructor needed, $self->{'printer'} deleted on destruction sub newDoc { my $self = shift; my $ed = ApplicationWindow->new; $ed->resize(400, 400); $ed->show(); } sub loadFile { shift->load(@_) } sub load { my $self = shift; my $e = $self->{'e'}; my $fileName = shift; unless($fileName) { my $fn = Qt::FileDialog::getOpenFileName(undef, undef, $self); if(defined $fn) { $self->load($fn); } else { $self->statusBar()->message("Loading aborted", 2000); } return; } return unless open(F, $fileName); $e->setAutoUpdate(0); $e->clear(); while(defined($s = )) { chomp($s); $e->append($s); } close(F); $e->setAutoUpdate(1); $e->repaint(); $self->setCaption($fileName); $self->statusBar()->message("Loaded document $fileName", 2000); } sub save { my $self = shift; $self->statusBar()->message("File->Save is not implemented"); Qt::MessageBox::information(undef, "Note", "Left as an exercise for the user."); } sub print { my $self = shift; my $e = $self->{'e'}; my $printer = $self->{'printer'}; my $MARGIN = 10; my $pageNo = 1; if($printer->setup($self)) { $self->statusBar()->message("Printing..."); my $p = Qt::Painter->new; $p->begin($printer); $p->setFont($e->font()); my $yPos = 0; my $fm = $p->fontMetrics(); my $metrics = Qt::PaintDeviceMetrics->new($printer); for(my $i = 0; $i < $e->numLines(); $i++) { if($MARGIN + $yPos > $metrics->height() - $MARGIN) { $self->statusBar()->message("Printing (page $pageNo)..."); $pageNo++; $printer->newPage(); $yPos = 0; } $p->drawText($MARGIN, $MARGIN + $yPos, $metrics->width(), $fm->lineSpacing(), Qt::ExpandTabs | Qt::DontClip, $e->textLine($i)); $yPos += $fm->lineSpacing(); } $p->end(); $self->statusBar()->message("Printing completed", 2000); } else { $self->statusBar()->message("Printing aborted", 2000); } } sub closeDoc { my $self = shift; $self->close(1); } sub toggleMenuBar { my $self = shift; my $controls = $self->{'controls'}; if($self->menuBar()->isVisible()) { $self->menuBar()->hide(); $controls->setItemChecked($self->{'mb'}, 0); } else { $self->menuBar()->show(); $controls->setItemChecked($self->{'mb'}, 1); } } sub toggleToolBar { my $self = shift; my $controls = $self->{'controls'}; my $fileTools = $self->{'fileTools'}; if($fileTools->isVisible()) { $fileTools->hide(); $controls->setItemChecked($self->{'tb'}, 0); } else { $fileTools->show(); $controls->setItemChecked($self->{'tb'}, 1); } } sub toggleStatusBar { my $self = shift; my $controls = $self->{'controls'}; if($self->statusBar()->isVisible()) { $self->statusBar()->hide(); $controls->setItemChecked($self->{'sb'}, 0); } else { $self->statusBar()->show(); $controls->setItemChecked($self->{'sb'}, 1); } }