import org.kde.qt.*;

public class ApplicationWindow extends QMainWindow {
	private QPrinter printer;
	private QMultiLineEdit e;
	private String filename;

	private final String fileOpenText = "<img source=\"fileopen\"> "+
					"Click this button to open a <em>new file</em>. <br><br>"+
					"You can also select the <b>Open command</b> from the File menu.";
	private final String 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.";
	private final String filePrintText = "Click this button to print the file you "+
					"are editing.\n\n"+
					"You can also select the Print command from the File menu.";

	private final String[] fileopen = {
		"    16    13        5            1",
		". c #040404",
		"# c #808304",
		"a c None",
		"b c #f3f704",
		"c c #f3f7f3",
		"aaaaaaaaa...aaaa",
		"aaaaaaaa.aaa.a.a",
		"aaaaaaaaaaaaa..a",
		"a...aaaaaaaa...a",
		".bcb.......aaaaa",
		".cbcbcbcbc.aaaaa",
		".bcbcbcbcb.aaaaa",
		".cbcb...........",
		".bcb.#########.a",
		".cb.#########.aa",
		".b.#########.aaa",
		"..#########.aaaa",
		"...........aaaaa"
	};

	private final String[] filesave = {
		"    14    14        4            1",
		". c #040404",
		"# c #808304",
		"a c #bfc2bf",
		"b c None",
		"..............",
		".#.aaaaaaaa.a.",
		".#.aaaaaaaa...",
		".#.aaaaaaaa.#.",
		".#.aaaaaaaa.#.",
		".#.aaaaaaaa.#.",
		".#.aaaaaaaa.#.",
		".##........##.",
		".############.",
		".##.........#.",
		".##......aa.#.",
		".##......aa.#.",
		".##......aa.#.",
		"b............."
	};
	
	private final String[] fileprint = {
		"    16    14        6            1",
		". c #000000",
		"# c #848284",
		"a c #c6c3c6",
		"b c #ffff00",
		"c c #ffffff",
		"d c None",
		"ddddd.........dd",
		"dddd.cccccccc.dd",
		"dddd.c.....c.ddd",
		"ddd.cccccccc.ddd",
		"ddd.c.....c....d",
		"dd.cccccccc.a.a.",
		"d..........a.a..",
		".aaaaaaaaaa.a.a.",
		".............aa.",
		".aaaaaa###aa.a.d",
		".aaaaaabbbaa...d",
		".............a.d",
		"d.aaaaaaaaa.a.dd",
		"dd...........ddd"
	};
	
	
	
	
	public ApplicationWindow() {
		super(null, "example application main window", WDestructiveClose);

		// create a printer

		printer = new QPrinter();


		// create user interface actions

		QAction fileNewAction, fileOpenAction, fileSaveAction,
				fileSaveAsAction, filePrintAction, fileCloseAction,
				fileQuitAction;

		fileNewAction = new QAction("New", "&New", new QKeySequence(CTRL+Key_N), this, "new", false);
		connect(fileNewAction, SIGNAL("activated()"), this, SLOT("newDoc()"));

		fileOpenAction = new QAction("Open File", new QIconSet(new QPixmap(fileopen)), "&Open", new QKeySequence(CTRL+Key_O), this, "open", false);
		connect(fileOpenAction, SIGNAL("activated()"), this, SLOT("load()"));
		QMimeSourceFactory.defaultFactory().setPixmap("fileopen", new QPixmap(fileopen));
		fileOpenAction.setWhatsThis(fileOpenText);

		fileSaveAction = new QAction("Save File", new QIconSet(new QPixmap(filesave)), "&Save", new QKeySequence(CTRL+Key_S), this, "save", false);
		connect(fileSaveAction, SIGNAL("activated()"), this, SLOT("save()"));
		fileSaveAction.setWhatsThis(fileSaveText);

		fileSaveAsAction = new QAction("Save File As", "Save &as", new QKeySequence(), this, "save as", false);
		connect(fileSaveAsAction, SIGNAL("activated()"), this, SLOT("saveAs()"));
		fileSaveAsAction.setWhatsThis(fileSaveText);

		filePrintAction = new QAction("Print File", new QIconSet(new QPixmap(fileprint)), "&Print", new QKeySequence(CTRL+Key_P), this, "print", false);
		connect(filePrintAction, SIGNAL("activated()"), this, SLOT("print()"));
		filePrintAction.setWhatsThis(filePrintText);

		fileCloseAction = new QAction("Close", "&Close", new QKeySequence(CTRL+Key_W), this, "close", false);
		connect(fileCloseAction, SIGNAL("activated()"), this, SLOT("close()"));

		fileQuitAction = new QAction("Quit", "&Quit", new QKeySequence(CTRL+Key_Q), this, "quit", false);
		connect(fileQuitAction, SIGNAL("activated()"), qApp(), SLOT("closeAllWindows()"));


		// populate a tool bar with some actions

		QToolBar fileTools = new QToolBar(this, "file operations");
		fileTools.setLabel(tr("File Operations"));
		fileOpenAction.addTo(fileTools);
		fileSaveAction.addTo(fileTools);
		filePrintAction.addTo(fileTools);
		QWhatsThis.whatsThisButton(fileTools);
		

		// popuplate a menu with all actions
		
		QPopupMenu file = new QPopupMenu(this, "file");
		menuBar().insertItem("&File", file);
		fileNewAction.addTo(file);
		fileOpenAction.addTo(file);
		fileSaveAction.addTo(file);
		fileSaveAsAction.addTo(file);
		file.insertSeparator();
		filePrintAction.addTo(file);
		file.insertSeparator();
		fileCloseAction.addTo(file);
		fileQuitAction.addTo(file);


		// add a help menu

		QPopupMenu help = new QPopupMenu(this, "help");
		menuBar().insertSeparator();
		menuBar().insertItem("&Help", help);
		help.insertItem("&About", this, SLOT("about()"), new QKeySequence(Key_F1), -1, -1);
		help.insertItem("About &Qt", this, SLOT("aboutQt()"));
		help.insertSeparator();
		help.insertItem("What's &This", this, SLOT("whatsThis()"), new QKeySequence(SHIFT+Key_F1), -1, -1);


		// create and define the central widget

		e = new QMultiLineEdit(this, "editor");
		e.setFocus();
		setCentralWidget(e);
		statusBar().message("Ready", 2000);
		resize(450, 600);
	}

	private void newDoc() {
		ApplicationWindow ed = new ApplicationWindow();
		ed.show();
	}

	private void load() {
		String fn = QFileDialog.getOpenFileName("", "", this);
		if (!(fn.length()==0))
			load(fn);
		else
			statusBar().message("Loading aborted", 2000);
	}


	private void load(String fileName) {
		QFile f = new QFile(fileName);
		if (!f.open(1))
			return;

		filename = fileName;

		e.setAutoUpdate(false);
		e.clear();

		QTextStream t = new QTextStream(f);
		while (!t.eof()) {
			String s = t.readLine();
			e.append(s);
		}
		f.close();

		e.setAutoUpdate(true);
		e.repaint();
		e.setEdited(false);
		setCaption(fileName);
		String s = "Loaded document "+fileName;
		statusBar().message(s, 2000);
	}

	private void save() {
		if (filename.length()==0) {
			saveAs();
			return;
		}

		String text = e.text();
		QFile f = new QFile(filename);
		if (!f.open(2)) {
			statusBar().message("Could not write to "+filename, 2000);
			return;
		}

		QTextStream t = new QTextStream(f);
		t.writeRawBytes(text, text.length());
		f.close();

		e.setEdited(false);

		setCaption(filename);

		statusBar().message("File "+filename+" saved", 2000);
	}


	private void saveAs() {
		String fn = QFileDialog.getSaveFileName("", "", this);
		if (!(fn.length()==0)) {
			filename = fn;
			save();
		} else {
			statusBar().message("Saving aborted", 2000);
		}
	}

	private void print() {
		final int Margin = 10;
		int pageNo = 1;

		if (printer.setup(this)) {   // printer dialog
			statusBar().message("Printing...");
			QPainter p = new QPainter();
			p.begin(printer);     // paint on printer
			p.setFont(e.font());
			int yPos = 0;      // y position for each line
			QFontMetrics fm = p.fontMetrics();
			
			// need width/height of printer surface
			QPaintDeviceMetrics metrics = new QPaintDeviceMetrics(printer);
			
			for(int i = 0 ; i < e.numLines() ; i++) {
				if (Margin + yPos > metrics.height() - Margin) {
					String msg = "Printing (page ";
					msg += ++pageNo;
					msg += ")...";
					statusBar().message(msg);
					printer.newPage();   // no more room on this page
					yPos = 0;     // back to top of page
				}
				p.drawText(Margin, Margin + yPos, metrics.width(),
						fm.lineSpacing(), ExpandTabs | DontClip, e.textLine(i));
				yPos = yPos + fm.lineSpacing();
			}
			p.end();        // send job to printer
			statusBar().message("Printing completed", 2000);
		} else {
			statusBar().message("Printing aborted", 2000);
		}
	}

	protected void closeEvent(QCloseEvent ce) {
		if (!e.edited()) {
			ce.accept();
			return;
		}

		switch(QMessageBox.information(this, "Qt Application Example",
					"The document has been changed since the last save.",
					"Save Now", "Cancel", "Leave Anyway", 0, 1)) {
			case 0:
				save();
				ce.accept();
				break;
			case 1:
			default: // just for sanity
				ce.ignore();
				break;
			case 2:
				ce.accept();
				break;
		}
	}

	private void about() {
		QMessageBox.about(this, "Qt Application Example",
				"This example demonstrates simple use of "+
				"QMainWindow,\nQMenuBar and QToolBar.");
	}


	private void aboutQt() {
		QMessageBox.aboutQt(this, "Qt Application Example");
	}
}
