source: trunk/examples/qwerty/qwerty.cpp@ 20

Last change on this file since 20 was 2, checked in by dmik, 20 years ago

Imported xplatform parts of the official release 3.3.1 from Trolltech

  • Property svn:keywords set to Id
File size: 9.3 KB
Line 
1/****************************************************************************
2** $Id: qwerty.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 "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
25const bool no_writing = FALSE;
26
27static QPtrList<QTextCodec> *codecList = 0;
28
29enum { Uni = 0, MBug = 1, Lat1 = 2, Local = 3, Guess = 4, Codec = 5 };
30
31
32Editor::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_T );
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
88Editor::~Editor()
89{
90}
91
92void 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
105void 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
131void 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
144void 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
153void 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
192void 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
202bool 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
213void 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
223void 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
252bool 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
277void 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
309void Editor::resizeEvent( QResizeEvent * )
310{
311 if ( e && m )
312 e->setGeometry( 0, m->height(), width(), height() - m->height() );
313}
314
315void 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
342void Editor::toUpper()
343{
344 e->setText(e->text().upper());
345}
346
347void Editor::toLower()
348{
349 e->setText(e->text().lower());
350}
351
352void Editor::textChanged()
353{
354 changed = TRUE;
355}
Note: See TracBrowser for help on using the repository browser.