home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / qt3_emx.zip / examples / qwerty / qwerty.cpp < prev    next >
C/C++ Source or Header  |  2001-10-11  |  9KB  |  356 lines

  1. /****************************************************************************
  2. ** $Id:  qt/qwerty.cpp   3.0.0   edited Oct 7 05:02 $
  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 "qwerty.h"
  12. #include <qapplication.h>
  13. #include <qfile.h>
  14. #include <qfiledialog.h>
  15. #include <qpopupmenu.h>
  16. #include <qtextstream.h>
  17. #include <qpainter.h>
  18. #include <qmessagebox.h>
  19. #include <qpaintdevicemetrics.h>
  20. #include <qptrlist.h>
  21. #include <qfontdialog.h>
  22.  
  23. #include <qtextcodec.h>
  24.  
  25. const bool no_writing = FALSE;
  26.  
  27. static QPtrList<QTextCodec> *codecList = 0;
  28.  
  29. enum { Uni = 0, MBug = 1, Lat1 = 2, Local = 3, Guess = 4, Codec = 5 };
  30.  
  31.  
  32. Editor::Editor( QWidget * parent , const char * name )
  33.     : QWidget( parent, name, WDestructiveClose )
  34. {
  35.     m = new QMenuBar( this, "menu" );
  36.  
  37.     QPopupMenu * file = new QPopupMenu();
  38.     Q_CHECK_PTR( file );
  39.     m->insertItem( "&File", file );
  40.  
  41.     file->insertItem( "&New",   this, SLOT(newDoc()),   ALT+Key_N );
  42.     file->insertItem( "&Open...",  this, SLOT(load()),     ALT+Key_O );
  43.     file->insertItem( "&Save...",  this, SLOT(save()),     ALT+Key_S );
  44.     file->insertSeparator();
  45.     open_as = new QPopupMenu();
  46.     file->insertItem( "Open &As",  open_as );
  47.     save_as = new QPopupMenu();
  48.     file->insertItem( "Sa&ve As",  save_as );
  49.     file->insertItem( "Add &Encoding", this, SLOT(addEncoding()) );    
  50. #ifndef QT_NO_PRINTER
  51.     file->insertSeparator();
  52.     file->insertItem( "&Print...", this, SLOT(print()),    ALT+Key_P );
  53. #endif
  54.     file->insertSeparator();
  55.     file->insertItem( "&Close", this, SLOT(close()),ALT+Key_W );
  56.     file->insertItem( "&Quit",  qApp, SLOT(closeAllWindows()),     ALT+Key_Q );
  57.  
  58.     connect( save_as, SIGNAL(activated(int)), this, SLOT(saveAsEncoding(int)) );
  59.     connect( open_as, SIGNAL(activated(int)), this, SLOT(openAsEncoding(int)) );
  60.     rebuildCodecList();
  61.  
  62.     QPopupMenu * edit = new QPopupMenu();
  63.     Q_CHECK_PTR( edit );
  64.     m->insertItem( "&Edit", edit );
  65.  
  66.     edit->insertItem( "To &Uppercase",   this, SLOT(toUpper()),   ALT+Key_U );
  67.     edit->insertItem( "To &Lowercase",   this, SLOT(toLower()),   ALT+Key_L );
  68. #ifndef QT_NO_FONTDIALOG
  69.     edit->insertSeparator();
  70.     edit->insertItem( "&Select Font" ,     this, SLOT(font()),     ALT+Key_F );
  71. #endif
  72.     changed = FALSE;
  73.     e = new QMultiLineEdit( this, "editor" );
  74.     connect( e, SIGNAL( textChanged() ), this, SLOT( textChanged() ) );
  75.  
  76.     // We use Unifont - if you have it installed you'll see all
  77.     // Unicode character glyphs.
  78.     //
  79.     // Unifont only comes in one pixel size, so we cannot let
  80.     // it change pixel size as the display DPI changes.
  81.     //
  82.     QFont unifont("unifont",16,50); unifont.setPixelSize(16);
  83.     e->setFont( unifont );
  84.  
  85.     e->setFocus();
  86. }
  87.  
  88. Editor::~Editor()
  89. {
  90. }
  91.  
  92. void Editor::font()
  93. {
  94. #ifndef QT_NO_FONTDIALOG
  95.     bool ok;
  96.     QFont f = QFontDialog::getFont( &ok, e->font() );
  97.     if ( ok ) {
  98.         e->setFont( f );
  99.     }
  100. #endif
  101. }
  102.  
  103.  
  104.  
  105. void Editor::rebuildCodecList()
  106. {
  107.     delete codecList;
  108.     codecList = new QPtrList<QTextCodec>;
  109.     QTextCodec *codec;
  110.     int i;
  111.     for (i = 0; (codec = QTextCodec::codecForIndex(i)); i++)
  112.     codecList->append( codec );
  113.     int n = codecList->count();
  114.     for (int pm=0; pm<2; pm++) {
  115.     QPopupMenu* menu = pm ? open_as : save_as;
  116.     menu->clear();
  117.     QString local = "Local (";
  118.     local += QTextCodec::codecForLocale()->name();
  119.     local += ")";
  120.     menu->insertItem( local, Local );
  121.     menu->insertItem( "Unicode", Uni );
  122.     menu->insertItem( "Latin1", Lat1 );
  123.     menu->insertItem( "Microsoft Unicode", MBug );
  124.     if ( pm )
  125.         menu->insertItem( "[guess]", Guess );
  126.     for ( i = 0; i < n; i++ )
  127.         menu->insertItem( codecList->at(i)->name(), Codec + i );
  128.     }
  129. }
  130.  
  131. void Editor::newDoc()
  132. {
  133.     Editor *ed = new Editor;
  134.     if ( qApp->desktop()->size().width() < 450
  135.      || qApp->desktop()->size().height() < 450 ) {
  136.     ed->showMaximized();
  137.     } else {
  138.     ed->resize( 400, 400 );
  139.     ed->show();
  140.     }
  141. }
  142.  
  143.  
  144. void Editor::load()
  145. {
  146. #ifndef QT_NO_FILEDIALOG
  147.     QString fn = QFileDialog::getOpenFileName( QString::null, QString::null, this );
  148.     if ( !fn.isEmpty() )
  149.     load( fn, -1 );
  150. #endif
  151. }
  152.  
  153. void Editor::load( const QString& fileName, int code )
  154. {
  155.     QFile f( fileName );
  156.     if ( !f.open( IO_ReadOnly ) )
  157.     return;
  158.  
  159.     e->setAutoUpdate( FALSE );
  160.  
  161.     QTextStream t(&f);
  162.     if ( code >= Codec )
  163.     t.setCodec( codecList->at(code-Codec) );
  164.     else if ( code == Uni )
  165.     t.setEncoding( QTextStream::Unicode );
  166.     else if ( code == MBug )
  167.     t.setEncoding( QTextStream::UnicodeReverse );
  168.     else if ( code == Lat1 )
  169.     t.setEncoding( QTextStream::Latin1 );
  170.     else if ( code == Guess ) {
  171.     QFile f(fileName);
  172.     f.open(IO_ReadOnly);
  173.     char buffer[256];
  174.     int l = 256;
  175.     l=f.readBlock(buffer,l);
  176.     QTextCodec* codec = QTextCodec::codecForContent(buffer, l);
  177.     if ( codec ) {
  178.         QMessageBox::information(this,"Encoding",QString("Codec: ")+codec->name());
  179.         t.setCodec( codec );
  180.     }
  181.     }
  182.     e->setText( t.read() );
  183.     f.close();
  184.  
  185.     e->setAutoUpdate( TRUE );
  186.     e->repaint();
  187.     setCaption( fileName );
  188.  
  189.     changed = FALSE;
  190. }
  191.  
  192. void Editor::openAsEncoding( int code )
  193. {
  194. #ifndef QT_NO_FILEDIALOG
  195.     //storing filename (proper save) is left as an exercise...
  196.     QString fn = QFileDialog::getOpenFileName( QString::null, QString::null, this );
  197.     if ( !fn.isEmpty() )
  198.     (void) load( fn, code );
  199. #endif
  200. }
  201.  
  202. bool Editor::save()
  203. {
  204. #ifndef QT_NO_FILEDIALOG
  205.     //storing filename (proper save) is left as an exercise...
  206.     QString fn = QFileDialog::getSaveFileName( QString::null, QString::null, this );
  207.     if ( !fn.isEmpty() )
  208.     return saveAs( fn );
  209.     return FALSE;
  210. #endif
  211. }
  212.  
  213. void Editor::saveAsEncoding( int code )
  214. {
  215. #ifndef QT_NO_FILEDIALOG
  216.     //storing filename (proper save) is left as an exercise...
  217.     QString fn = QFileDialog::getSaveFileName( QString::null, QString::null, this );
  218.     if ( !fn.isEmpty() )
  219.     (void) saveAs( fn, code );
  220. #endif
  221. }
  222.  
  223. void Editor::addEncoding()
  224. {
  225. #ifndef QT_NO_FILEDIALOG
  226.     QString fn = QFileDialog::getOpenFileName( QString::null, "*.map", this );
  227.     if ( !fn.isEmpty() ) {
  228.     QFile f(fn);
  229.     if (f.open(IO_ReadOnly)) {
  230.         if (QTextCodec::loadCharmap(&f)) {
  231.         rebuildCodecList();
  232.         } else {
  233.         QMessageBox::warning(0,"Charmap error",
  234.             "The file did not contain a valid charmap.\n\n"
  235.             "A charmap file should look like this:\n"
  236.                "  <code_set_name> thename\n"
  237.                "  <escape_char> /\n"
  238.                "  % alias thealias\n"
  239.                "  CHARMAP\n"
  240.                "  <tokenname> /x12 <U3456>\n"
  241.                "  <tokenname> /xAB/x12 <U0023>\n"
  242.                "  ...\n"
  243.                "  END CHARMAP\n"
  244.         );
  245.         }
  246.     }
  247.     }
  248. #endif
  249. }
  250.  
  251.  
  252. bool Editor::saveAs( const QString& fileName, int code )
  253. {
  254.     QFile f( fileName );
  255.     if ( no_writing || !f.open( IO_WriteOnly ) ) {
  256.     QMessageBox::warning(this,"I/O Error",
  257.             QString("The file could not be opened.\n\n")
  258.             +fileName);
  259.     return FALSE;
  260.     }
  261.     QTextStream t(&f);
  262.     if ( code >= Codec )
  263.     t.setCodec( codecList->at(code-Codec) );
  264.     else if ( code == Uni )
  265.     t.setEncoding( QTextStream::Unicode );
  266.     else if ( code == MBug )
  267.     t.setEncoding( QTextStream::UnicodeReverse );
  268.     else if ( code == Lat1 )
  269.     t.setEncoding( QTextStream::Latin1 );
  270.     t << e->text();
  271.     f.close();
  272.     setCaption( fileName );
  273.     changed = FALSE;
  274.     return TRUE;
  275. }
  276.  
  277. void Editor::print()
  278. {
  279. #ifndef QT_NO_PRINTER
  280.     if ( printer.setup(this) ) {        // opens printer dialog
  281.     printer.setFullPage(TRUE);        // we'll set our own margins
  282.     QPainter p;
  283.     p.begin( &printer );            // paint on printer
  284.     p.setFont( e->font() );
  285.     QFontMetrics fm = p.fontMetrics();
  286.     QPaintDeviceMetrics metrics( &printer ); // need width/height
  287.                          // of printer surface
  288.     const int MARGIN = metrics.logicalDpiX() / 2; // half-inch margin
  289.     int yPos        = MARGIN;        // y position for each line
  290.  
  291.     for( int i = 0 ; i < e->numLines() ; i++ ) {
  292.         if ( printer.aborted() )
  293.         break;
  294.         if ( yPos + fm.lineSpacing() > metrics.height() - MARGIN ) {
  295.         // no more room on this page
  296.         if ( !printer.newPage() )          // start new page
  297.             break;                           // some error
  298.         yPos = MARGIN;             // back to top of page
  299.         }
  300.         p.drawText( MARGIN, yPos, metrics.width() - 2*MARGIN,
  301.             fm.lineSpacing(), ExpandTabs, e->textLine( i ) );
  302.         yPos += fm.lineSpacing();
  303.     }
  304.     p.end();                // send job to printer
  305.     }
  306. #endif
  307. }
  308.  
  309. void Editor::resizeEvent( QResizeEvent * )
  310. {
  311.     if ( e && m )
  312.     e->setGeometry( 0, m->height(), width(), height() - m->height() );
  313. }
  314.  
  315. void Editor::closeEvent( QCloseEvent *event )
  316. {
  317.     event->accept();
  318.  
  319.     if ( changed ) { // the text has been changed
  320.     switch ( QMessageBox::warning( this, "Qwerty",
  321.                     "Save changes to Document?",
  322.                     tr("&Yes"),
  323.                     tr("&No"),
  324.                     tr("Cancel"),
  325.                     0, 2) ) {
  326.     case 0: // yes
  327.         if ( save() )
  328.         event->accept();
  329.         else
  330.         event->ignore();
  331.         break;
  332.     case 1: // no
  333.         event->accept();
  334.         break;
  335.     default: // cancel
  336.         event->ignore();
  337.         break;
  338.     }
  339.     }
  340. }
  341.  
  342. void Editor::toUpper()
  343. {
  344.     e->setText(e->text().upper());
  345. }
  346.  
  347. void Editor::toLower()
  348. {
  349.     e->setText(e->text().lower());
  350. }
  351.  
  352. void Editor::textChanged()
  353. {
  354.     changed = TRUE;
  355. }
  356.