summaryrefslogtreecommitdiff
path: root/core/apps/textedit/textedit.cpp
Unidiff
Diffstat (limited to 'core/apps/textedit/textedit.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--core/apps/textedit/textedit.cpp594
1 files changed, 594 insertions, 0 deletions
diff --git a/core/apps/textedit/textedit.cpp b/core/apps/textedit/textedit.cpp
new file mode 100644
index 0000000..867625e
--- a/dev/null
+++ b/core/apps/textedit/textedit.cpp
@@ -0,0 +1,594 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include "textedit.h"
22
23#include <qpe/global.h>
24#include <qpe/fileselector.h>
25#include <qpe/applnk.h>
26#include <qpe/resource.h>
27#include <qpe/config.h>
28#include <qpe/qpeapplication.h>
29#include <qpe/qpemenubar.h>
30#include <qpe/qpetoolbar.h>
31//#include <qpe/finddialog.h>
32
33#include <qaction.h>
34#include <qcolordialog.h>
35#include <qfileinfo.h>
36#include <qlineedit.h>
37#include <qmessagebox.h>
38#include <qobjectlist.h>
39#include <qpopupmenu.h>
40#include <qspinbox.h>
41#include <qtoolbutton.h>
42#include <qwidgetstack.h>
43
44#include <stdlib.h> //getenv
45
46
47#if QT_VERSION < 300
48
49class QpeEditor : public QMultiLineEdit
50{
51 // Q_OBJECT
52public:
53 QpeEditor( QWidget *parent, const char * name = 0 )
54 : QMultiLineEdit( parent, name ) {}
55
56 //public slots:
57 void find( const QString &txt, bool caseSensitive,
58 bool backwards );
59 /*
60signals:
61 void notFound();
62 void searchWrapped();
63 */
64
65private:
66
67};
68
69
70void QpeEditor::find ( const QString &txt, bool caseSensitive,
71 bool backwards )
72{
73 static bool wrap = FALSE;
74 int line, col;
75 if ( wrap ) {
76 if ( !backwards )
77 line = col = 0;
78 wrap = FALSE;
79 //emit searchWrapped();
80 } else {
81 getCursorPosition( &line, &col );
82 }
83 //ignore backwards for now....
84 if ( !backwards ) {
85 for ( ; ; ) {
86 if ( line >= numLines() ) {
87 wrap = TRUE;
88 //emit notFound();
89 break;
90 }
91 int findCol = getString( line )->find( txt, col, caseSensitive );
92 if ( findCol >= 0 ) {
93 setCursorPosition( line, findCol, FALSE );
94 col = findCol + txt.length();
95 setCursorPosition( line, col, TRUE );
96
97 //found = TRUE;
98 break;
99 }
100 line++;
101 col = 0;
102 }
103
104 }
105
106}
107
108
109#else
110
111#error "Must make a QpeEditor that inherits QTextEdit"
112
113#endif
114
115
116
117
118static int u_id = 1;
119static int get_unique_id()
120{
121 return u_id++;
122}
123
124static const int nfontsizes = 6;
125static const int fontsize[nfontsizes] = {8,10,12,14,18,24};
126
127TextEdit::TextEdit( QWidget *parent, const char *name, WFlags f )
128 : QMainWindow( parent, name, f ), bFromDocView( FALSE )
129{
130 doc = 0;
131
132 QString lang = getenv( "LANG" );
133
134 setToolBarsMovable( FALSE );
135
136 setIcon( Resource::loadPixmap( "TextEditor" ) );
137
138 QPEToolBar *bar = new QPEToolBar( this );
139 bar->setHorizontalStretchable( TRUE );
140 menu = bar;
141
142 QPEMenuBar *mb = new QPEMenuBar( bar );
143 QPopupMenu *file = new QPopupMenu( this );
144 QPopupMenu *edit = new QPopupMenu( this );
145 QPopupMenu *font = new QPopupMenu( this );
146
147 bar = new QPEToolBar( this );
148 editBar = bar;
149
150 QAction *a = new QAction( tr( "New" ), Resource::loadPixmap( "new" ), QString::null, 0, this, 0 );
151 connect( a, SIGNAL( activated() ), this, SLOT( fileNew() ) );
152 a->addTo( bar );
153 a->addTo( file );
154
155 a = new QAction( tr( "Open" ), Resource::loadPixmap( "fileopen" ), QString::null, 0, this, 0 );
156 connect( a, SIGNAL( activated() ), this, SLOT( fileOpen() ) );
157 a->addTo( bar );
158 a->addTo( file );
159
160 a = new QAction( tr( "Cut" ), Resource::loadPixmap( "cut" ), QString::null, 0, this, 0 );
161 connect( a, SIGNAL( activated() ), this, SLOT( editCut() ) );
162 a->addTo( editBar );
163 a->addTo( edit );
164
165 a = new QAction( tr( "Copy" ), Resource::loadPixmap( "copy" ), QString::null, 0, this, 0 );
166 connect( a, SIGNAL( activated() ), this, SLOT( editCopy() ) );
167 a->addTo( editBar );
168 a->addTo( edit );
169
170 a = new QAction( tr( "Paste" ), Resource::loadPixmap( "paste" ), QString::null, 0, this, 0 );
171 connect( a, SIGNAL( activated() ), this, SLOT( editPaste() ) );
172 a->addTo( editBar );
173 a->addTo( edit );
174
175 a = new QAction( tr( "Find..." ), Resource::loadPixmap( "find" ), QString::null, 0, this, 0 );
176 connect( a, SIGNAL( activated() ), this, SLOT( editFind() ) );
177 edit->insertSeparator();
178 a->addTo( bar );
179 a->addTo( edit );
180
181 int defsize;
182 bool defb, defi, wrap;
183 {
184 Config cfg("TextEdit");
185 cfg.setGroup("View");
186 defsize = cfg.readNumEntry("FontSize",10);
187 defb = cfg.readBoolEntry("Bold",FALSE);
188 defi = cfg.readBoolEntry("Italic",FALSE);
189 wrap = cfg.readBoolEntry("Wrap",TRUE);
190 }
191
192 zin = new QAction( tr("Zoom in"), QString::null, 0, this, 0 );
193 connect( zin, SIGNAL( activated() ), this, SLOT( zoomIn() ) );
194 zin->addTo( font );
195
196 zout = new QAction( tr("Zoom out"), QString::null, 0, this, 0 );
197 connect( zout, SIGNAL( activated() ), this, SLOT( zoomOut() ) );
198 zout->addTo( font );
199
200 font->insertSeparator();
201
202#if 0
203 QAction *ba = new QAction( tr("Bold"), QString::null, 0, this, 0 );
204 connect( ba, SIGNAL( toggled(bool) ), this, SLOT( setBold(bool) ) );
205 ba->setToggleAction(TRUE);
206 ba->addTo( font );
207
208 QAction *ia = new QAction( tr("Italic"), QString::null, 0, this, 0 );
209 connect( ia, SIGNAL( toggled(bool) ), this, SLOT( setItalic(bool) ) );
210 ia->setToggleAction(TRUE);
211 ia->addTo( font );
212
213 ba->setOn(defb);
214 ia->setOn(defi);
215
216 font->insertSeparator();
217#endif
218
219 QAction *wa = new QAction( tr("Wrap lines"), QString::null, 0, this, 0 );
220 connect( wa, SIGNAL( toggled(bool) ), this, SLOT( setWordWrap(bool) ) );
221 wa->setToggleAction(TRUE);
222 wa->addTo( font );
223
224 mb->insertItem( tr( "File" ), file );
225 mb->insertItem( tr( "Edit" ), edit );
226 mb->insertItem( tr( "View" ), font );
227
228 searchBar = new QPEToolBar(this);
229 addToolBar( searchBar, "Search", QMainWindow::Top, TRUE );
230
231 searchBar->setHorizontalStretchable( TRUE );
232
233 searchEdit = new QLineEdit( searchBar, "searchEdit" );
234 searchBar->setStretchableWidget( searchEdit );
235 connect( searchEdit, SIGNAL( textChanged( const QString & ) ),
236 this, SLOT( search() ) );
237
238 a = new QAction( tr( "Find Next" ), Resource::loadPixmap( "next" ), QString::null, 0, this, 0 );
239 connect( a, SIGNAL( activated() ), this, SLOT( findNext() ) );
240 a->addTo( searchBar );
241 a->addTo( edit );
242
243 a = new QAction( tr( "Close Find" ), Resource::loadPixmap( "close" ), QString::null, 0, this, 0 );
244 connect( a, SIGNAL( activated() ), this, SLOT( findClose() ) );
245 a->addTo( searchBar );
246
247 searchBar->hide();
248
249 editorStack = new QWidgetStack( this );
250 setCentralWidget( editorStack );
251
252 searchVisible = FALSE;
253
254 fileSelector = new FileSelector( "text/*", editorStack, "fileselector" ,
255 TRUE, FALSE );
256 fileSelector->setCategoriesVisible(TRUE);
257 connect( fileSelector, SIGNAL( closeMe() ), this, SLOT( showEditTools() ) );
258 connect( fileSelector, SIGNAL( newSelected( const DocLnk &) ), this, SLOT( newFile( const DocLnk & ) ) );
259 connect( fileSelector, SIGNAL( fileSelected( const DocLnk &) ), this, SLOT( openFile( const DocLnk & ) ) );
260 fileOpen();
261
262 editor = new QpeEditor( editorStack );
263 editorStack->addWidget( editor, get_unique_id() );
264
265 resize( 200, 300 );
266
267 setFontSize(defsize,TRUE);
268 wa->setOn(wrap);
269}
270
271TextEdit::~TextEdit()
272{
273 save();
274
275 Config cfg("TextEdit");
276 cfg.setGroup("View");
277 QFont f = editor->font();
278 cfg.writeEntry("FontSize",f.pointSize());
279 cfg.writeEntry("Bold",f.bold());
280 cfg.writeEntry("Italic",f.italic());
281 cfg.writeEntry("Wrap",editor->wordWrap() == QMultiLineEdit::WidgetWidth);
282}
283
284void TextEdit::zoomIn()
285{
286 setFontSize(editor->font().pointSize()+1,FALSE);
287}
288
289void TextEdit::zoomOut()
290{
291 setFontSize(editor->font().pointSize()-1,TRUE);
292}
293
294
295void TextEdit::setFontSize(int sz, bool round_down_not_up)
296{
297 int s=10;
298 for (int i=0; i<nfontsizes; i++) {
299 if ( fontsize[i] == sz ) {
300 s = sz;
301 break;
302 } else if ( round_down_not_up ) {
303 if ( fontsize[i] < sz )
304 s = fontsize[i];
305 } else {
306 if ( fontsize[i] > sz ) {
307 s = fontsize[i];
308 break;
309 }
310 }
311 }
312
313 QFont f = editor->font();
314 f.setPointSize(s);
315 editor->setFont(f);
316
317 zin->setEnabled(s != fontsize[nfontsizes-1]);
318 zout->setEnabled(s != fontsize[0]);
319}
320
321void TextEdit::setBold(bool y)
322{
323 QFont f = editor->font();
324 f.setBold(y);
325 editor->setFont(f);
326}
327
328void TextEdit::setItalic(bool y)
329{
330 QFont f = editor->font();
331 f.setItalic(y);
332 editor->setFont(f);
333}
334
335void TextEdit::setWordWrap(bool y)
336{
337 editor->setWordWrap(y ? QMultiLineEdit::WidgetWidth : QMultiLineEdit::NoWrap );
338}
339
340void TextEdit::fileNew()
341{
342 save();
343 newFile(DocLnk());
344}
345
346void TextEdit::fileOpen()
347{
348 if ( !save() ) {
349 if ( QMessageBox::critical( this, tr( "Out of space" ),
350 tr( "Text Editor was unable to\n"
351 "save your changes.\n"
352 "Free some space and try again.\n"
353 "\nContinue anyway?" ),
354 QMessageBox::Yes|QMessageBox::Escape,
355 QMessageBox::No|QMessageBox::Default )
356 != QMessageBox::Yes )
357 return;
358 else {
359 delete doc;
360 doc = 0;
361 }
362 }
363 menu->hide();
364 editBar->hide();
365 searchBar->hide();
366 clearWState (WState_Reserved1 );
367 editorStack->raiseWidget( fileSelector );
368 fileSelector->reread();
369 updateCaption();
370}
371
372
373#if 0
374void TextEdit::slotFind()
375{
376 FindDialog frmFind( "Text Editor", this );
377 connect( &frmFind, SIGNAL(signalFindClicked(const QString &, bool, bool, int)),
378 editor, SLOT(slotDoFind( const QString&,bool,bool)));
379
380 //case sensitive, backwards, [category]
381
382
383 connect( editor, SIGNAL(notFound()),
384 &frmFind, SLOT(slotNotFound()) );
385 connect( editor, SIGNAL(searchWrapped()),
386 &frmFind, SLOT(slotWrapAround()) );
387
388 frmFind.exec();
389
390
391}
392#endif
393
394void TextEdit::fileRevert()
395{
396 clear();
397 fileOpen();
398}
399
400void TextEdit::editCut()
401{
402#ifndef QT_NO_CLIPBOARD
403 editor->cut();
404#endif
405}
406
407void TextEdit::editCopy()
408{
409#ifndef QT_NO_CLIPBOARD
410 editor->copy();
411#endif
412}
413
414void TextEdit::editPaste()
415{
416#ifndef QT_NO_CLIPBOARD
417 editor->paste();
418#endif
419}
420
421void TextEdit::editFind()
422{
423 searchBar->show();
424 searchVisible = TRUE;
425 searchEdit->setFocus();
426}
427
428void TextEdit::findNext()
429{
430 editor->find( searchEdit->text(), FALSE, FALSE );
431
432}
433
434void TextEdit::findClose()
435{
436 searchVisible = FALSE;
437 searchBar->hide();
438}
439
440void TextEdit::search()
441{
442 editor->find( searchEdit->text(), FALSE, FALSE );
443}
444
445void TextEdit::newFile( const DocLnk &f )
446{
447 DocLnk nf = f;
448 nf.setType("text/plain");
449 clear();
450 editorStack->raiseWidget( editor );
451 setWState (WState_Reserved1 );
452 editor->setFocus();
453 doc = new DocLnk(nf);
454 updateCaption();
455}
456
457void TextEdit::openFile( const QString &f )
458{
459 bFromDocView = TRUE;
460 DocLnk nf;
461 nf.setType("text/plain");
462 nf.setFile(f);
463 openFile(nf);
464 showEditTools();
465 // Show filename in caption
466 QString name = f;
467 int sep = name.findRev( '/' );
468 if ( sep > 0 )
469 name = name.mid( sep+1 );
470 updateCaption( name );
471}
472
473void TextEdit::openFile( const DocLnk &f )
474{
475 clear();
476 FileManager fm;
477 QString txt;
478 if ( !fm.loadFile( f, txt ) ) {
479 // ####### could be a new file
480 //qDebug( "Cannot open file" );
481 //return;
482 }
483 fileNew();
484 if ( doc )
485 delete doc;
486 doc = new DocLnk(f);
487 editor->setText(txt);
488 editor->setEdited(FALSE);
489 updateCaption();
490}
491
492void TextEdit::showEditTools()
493{
494 if ( !doc )
495 close();
496 fileSelector->hide();
497 menu->show();
498 editBar->show();
499 if ( searchVisible )
500 searchBar->show();
501 updateCaption();
502}
503
504bool TextEdit::save()
505{
506 // case of nothing to save...
507 if ( !doc )
508 return true;
509 if ( !editor->edited() ) {
510 delete doc;
511 doc = 0;
512 return true;
513 }
514
515 QString rt = editor->text();
516
517 if ( doc->name().isEmpty() ) {
518 QString pt = rt.simplifyWhiteSpace();
519 int i = pt.find( ' ' );
520 QString docname = pt;
521 if ( i > 0 )
522 docname = pt.left( i );
523 // remove "." at the beginning
524 while( docname.startsWith( "." ) )
525 docname = docname.mid( 1 );
526 docname.replace( QRegExp("/"), "_" );
527 // cut the length. filenames longer than that don't make sense and something goes wrong when they get too long.
528 if ( docname.length() > 40 )
529 docname = docname.left(40);
530 if ( docname.isEmpty() )
531 docname = "Empty Text";
532 doc->setName(docname);
533
534 // append .txt to the file name
535 if ( doc->file().find(".txt") == -1 ) {
536 QString file = doc->file() + ".txt";
537 doc->setFile( file );
538 }
539 }
540
541
542 FileManager fm;
543 if ( !fm.saveFile( *doc, rt ) ) {
544 return false;
545 }
546 delete doc;
547 doc = 0;
548 editor->setEdited( false );
549 return true;
550}
551
552void TextEdit::clear()
553{
554 delete doc;
555 doc = 0;
556 editor->clear();
557}
558
559void TextEdit::updateCaption( const QString &name )
560{
561 if ( !doc )
562 setCaption( tr("Text Editor") );
563 else {
564 QString s = name;
565 if ( s.isNull() )
566 s = doc->name();
567 if ( s.isEmpty() )
568 s = tr( "Unnamed" );
569 setCaption( s + " - " + tr("Text Editor") );
570 }
571}
572
573void TextEdit::setDocument(const QString& fileref)
574{
575 bFromDocView = TRUE;
576 openFile(DocLnk(fileref));
577 showEditTools();
578}
579
580void TextEdit::closeEvent( QCloseEvent *e )
581{
582 if ( editorStack->visibleWidget() == editor && !bFromDocView ) {
583 e->ignore();
584 fileRevert();
585 } else {
586 bFromDocView = FALSE;
587 e->accept();
588 }
589}
590
591void TextEdit::accept()
592{
593 fileOpen();
594 }