PortableGUI |
Hosted by SourceForge Project page |
// Import all PortableGUI include files #include <portablegui.h> // Blocksize for load/save operations #define BLOCKSIZE 4000 // Text field for editing PGTextArea* g_textArea; // Main frame window PGFrame* g_mainFrame; // Filter for filenames char* g_sFilter = "Text files (*.txt)$*.txt$All files (*.*)$*.*$"; // File already named? BOOL g_bHasName = FALSE; PGString g_sFile; // Image for about box PGImage* g_imageAbout; // Icon for Win/GNOME taskbar PGIcon* g_icon; // Forward declarations for new, open and save methods BOOL doNew(); BOOL doOpen(); BOOL doSave(BOOL verifyOverwrite); // Update the window title bar void UpdateTitle(); // Called when user tries to close the main window class MyWindowListener : public PGWindowListener { virtual void windowClosing(PGWindow* wnd) { // Exit the application getPGApplication()->exit(0); } }; // Called when user selects File | Exit class MyExitListener : public PGActionListener { // Exit the application virtual void actionPerformed(PGCallback* from) { getPGApplication()->exit(0); } }; // Called when user selects File | New class MyNewListener : public PGActionListener { // Call doNew and update windows title virtual void actionPerformed(PGCallback* from) { if (doNew()) g_bHasName = FALSE; UpdateTitle(); } }; // Called when user selects File | Open class MyOpenListener : public PGActionListener { // Open file virtual void actionPerformed(PGCallback* from) { // Create file open dialog PGFileDialog dial("Open"); dial.setFilter(g_sFilter); if (g_bHasName) dial.setFile(g_sFile.getValue()); // Display file open dialog if (dial.showFileOpenDialog(g_mainFrame)) { g_sFile.setCopyValue(dial.m_sFile.getValue()); g_bHasName = doOpen(); UpdateTitle(); } } }; // Called when user selects File | Save class MySaveListener : public PGActionListener { virtual void actionPerformed(PGCallback* from) { if (!g_bHasName) { // Create file dialog if file has no name yet PGFileDialog dial("Save"); dial.setFilter(g_sFilter); // Display file dialog if (dial.showFileSaveDialog(g_mainFrame)) { g_sFile.setCopyValue(dial.m_sFile.getValue()); } else { return; } } // Save file and update window title g_bHasName = doSave(FALSE); UpdateTitle(); } }; // Called when user selects File | Save As class MySaveAsListener : public PGActionListener { virtual void actionPerformed(PGCallback* from) { // Create save as file dialog PGFileDialog dial("Save As"); dial.setFilter(g_sFilter); if (g_bHasName) dial.setFile(g_sFile.getValue()); // Display dialog, save and update title if (dial.showFileSaveDialog(g_mainFrame)) { g_sFile.setCopyValue(dial.m_sFile.getValue()); g_bHasName = doSave(TRUE); UpdateTitle(); } } }; // Does GtkText support undo? #ifdef PGWIN // Called when user selects File | Undo class MyUndoListener : public PGActionListener { virtual void actionPerformed(PGCallback* from) { g_textArea->undoOperation(); } }; #endif // Called when user selects Edit | Cut class MyCutListener : public PGActionListener { virtual void actionPerformed(PGCallback* from) { g_textArea->cut(); } }; // Called when user selects Edit | Copy class MyCopyListener : public PGActionListener { virtual void actionPerformed(PGCallback* from) { g_textArea->copy(); } }; // Called when user selects Edit | Paste class MyPasteListener : public PGActionListener { virtual void actionPerformed(PGCallback* from) { g_textArea->paste(); } }; // Called when user selects Edit | Select All class MySelectAllListener : public PGActionListener { virtual void actionPerformed(PGCallback* from) { g_textArea->selectAll(); } }; // Called when user tries to close the about window class AboutWindowListener : public PGWindowListener { virtual void windowClosing(PGWindow* wnd) { wnd->dispose(); } }; // Called when user clicks 'Close' button class MyWindowCloseListener : public PGActionListener { private: PGWindow* m_Window; public: MyWindowCloseListener(PGWindow* window) { m_Window = window; } virtual void actionPerformed(PGCallback* from) { m_Window->dispose(); } }; // Called when user selects Help | About class MyAboutListener : public PGActionListener { virtual void actionPerformed(PGCallback* from) { // Create a new style (used for the about label) PGStyle* style = new PGStyle(); style->setFont(new PGFont("", PGFONT_BOLD | PGFONT_ITALIC, 16)); // Create about dialog PGDialog about(g_mainFrame, "About EditPad"); about.setIconImage(g_icon); about.addWindowListener(new AboutWindowListener()); /*** * Percentlayout * Component 1 : pl = Preferred size, Left justify * 2 : 20d = Dummy component size 20 pixels * 3 : 100% = 100% Stretch of leftover space * 5 : pc = Preferred size, Center justify */ about.setLayout(new PGPercentLayout("pl 5d 100% 5d pl pl 10d pc", 3, PGPERCENTLAYOUT_ALL, TRUE)); // Create about label with large font style style PGLabel* label = new PGLabel("PortableGUI - EditPad demo"); label->setStyle(style); about.add(label); // Create image viewer and some other labels about.add(new PGImageViewer(g_imageAbout)); about.add(new PGLabel("Written by Jan Struyf")); about.add(new PGLabel("jan.struyf@cs.kuleuven.ac.be")); // Create and add close button PGButton* ok = new PGButton(" &Close ", TRUE); ok->addActionListener(new MyWindowCloseListener(&about)); about.add(ok); // Pack components in window and show modal about.pack(); about.doModal(); } }; // Update window title bar void UpdateTitle() { PGString myTitle; myTitle.setCopyValue(g_sFile.getValue()); // Check if filename too long int len = myTitle.getLength(); if (len > 18) { myTitle.substring(len-18, len); myTitle.prepend("EditPad - .."); } else { myTitle.prepend("EditPad - "); } // Set the filename in the title bar g_mainFrame->setTitle(myTitle.getValue()); } // Clear text component BOOL doNew() { g_textArea->setText(""); return TRUE; } // Save file to disk BOOL doSave(BOOL verifyOverwrite) { if (verifyOverwrite) { // Check if file exists PGFileInputStream input(g_sFile.getValue()); if (input.getError() == PGINPUTSTREAM_ERROR_NONE) { // File already exists, show message box input.close(); PGMessageBox box("Save file","File already exists, overwrite?",PGMSGBOX_YES | PGMSGBOX_NO | PGMSGBOX_ICONQUESTION); if (box.show(g_mainFrame) != PGMSGBOX_YES) return FALSE; } } // Try to open file for output PGFileOutputStream output(g_sFile.getValue()); if (output.getError() != PGOUTPUTSTREAM_ERROR_NONE) { // Can't open file, show message box PGMessageBox box("Save file","Can't create file",PGMSGBOX_OK | PGMSGBOX_ICONERROR); box.show(g_mainFrame); return FALSE; } // Copy contents of textarea to file PGString str; long tot = 0; // Don't update text component each block (works in GTK only) g_textArea->setDirectUpdate(FALSE); long len = g_textArea->getSize(); // Block max size is BLOCKSIZE do { // Calculate size for next block long now = MIN2(BLOCKSIZE, len-tot); // Get text block from text area and write to disk g_textArea->getText(&str, tot, tot+now); int nb = output.write((unsigned char*)str.getValue(), 0, now); // Maybe out of quota? disk full? if (nb != (int)now) { output.close(); PGMessageBox box("Save file","Disk full",PGMSGBOX_OK | PGMSGBOX_ICONERROR); box.show(g_mainFrame); return FALSE; } tot += now; } while (tot < len); g_textArea->setDirectUpdate(TRUE); // Close file and return true output.close(); return TRUE; } // Load file from disk BOOL doOpen() { if (!doNew()) return FALSE; // Try to open file PGFileInputStream input(g_sFile.getValue()); if (input.getError() != PGINPUTSTREAM_ERROR_NONE) { // Can't open file, display message box PGMessageBox box("Open file","File not found",PGMSGBOX_OK | PGMSGBOX_ICONERROR); box.show(g_mainFrame); return FALSE; } long tot = 0; size_t nb = 0; // Don't update text component each block (works in GTK only) g_textArea->setDirectUpdate(FALSE); PGString str; str.allocateNew(BLOCKSIZE+1); do { // Read in next block nb = input.read((unsigned char*)str.getValue(), 0, BLOCKSIZE); str.substring(0, nb-1); tot += nb; // Append block to text area g_textArea->append(str.getValue(), FALSE); } while (nb == BLOCKSIZE); g_textArea->setDirectUpdate(TRUE); input.close(); #ifdef PGWIN // Maximum size for edit in windows // So, for a serious edit app, you have to write your own edit component if (tot > 32000) { PGMessageBox box("Open file","File too large for editor",PGMSGBOX_OK | PGMSGBOX_ICONERROR); box.show(g_mainFrame); return FALSE; } #endif return TRUE; } // Create the main menu PGMenuBar* makeMenu() { PGMenuBar* bar= new PGMenuBar(); // Create file menu PGMenu* menu = new PGMenu("&File"); PGMenuItem* item = new PGMenuItem("&New"); item->addActionListener(new MyNewListener()); menu->add(item); item = new PGMenuItem("&Open"); item->addActionListener(new MyOpenListener()); menu->add(item); item = new PGMenuItem("&Close"); menu->add(item); menu->add(new PGMenuSeparator()); item = new PGMenuItem("&Save"); item->addActionListener(new MySaveListener()); menu->add(item); item = new PGMenuItem("Save &As"); item->addActionListener(new MySaveAsListener()); menu->add(item); menu->add(new PGMenuSeparator()); item = new PGMenuItem("&Exit"); item->addActionListener(new MyExitListener()); menu->add(item); bar->add(menu); // Create edit menu menu = new PGMenu("&Edit"); #ifdef PGWIN item = new PGMenuItem("&Undo"); item->addActionListener(new MyUndoListener()); menu->add(item); menu->add(new PGMenuSeparator()); #endif item = new PGMenuItem("Cu&t"); item->addActionListener(new MyCutListener()); menu->add(item); item = new PGMenuItem("&Copy"); item->addActionListener(new MyCopyListener()); menu->add(item); item = new PGMenuItem("&Paste"); item->addActionListener(new MyPasteListener()); menu->add(item); item = new PGMenuItem("Select A&ll"); item->addActionListener(new MySelectAllListener()); menu->add(item); bar->add(menu); // Create help menu menu = new PGMenu("&Help"); item = new PGMenuItem("&About"); item->addActionListener(new MyAboutListener()); menu->add(item); bar->add(menu); return bar; } // Mainproc is different for Windows and GTK PGMAINPROC { PGApplication app; // Initialize the app using Mainproc args PGINIT(app); // Create main frame window g_mainFrame = new PGFrame("EditPad"); PGINCREF(g_mainFrame); // Load about pixmap (BMP fileformat 4 or 8 bits/pixel) g_imageAbout = new PGImage("../about.bmp", g_mainFrame); PGINCREF(g_imageAbout); // Load icon for main window PGColor background(178,178,180); g_icon = new PGIcon(new PGImage("../icon.bmp", &background, g_mainFrame)); g_mainFrame->setIconImage(g_icon); // Add window listener to frame g_mainFrame->addWindowListener(new MyWindowListener()); // Use simple layoutmanager for the edit control g_mainFrame->setLayout(new PGBorderLayout(2,2,0,0)); // Create main menu and add menu bar g_mainFrame->setMenuBar(makeMenu()); // Add text area for editing g_textArea = new PGTextArea("", 30, 40, PGTEXTAREA_SCROLLBARS_VERTICAL_ONLY); PGINCREF(g_textArea); g_mainFrame->add(g_textArea, PGBORDERLAYOUT_CENTER); // Pack and show the frame g_mainFrame->pack(); g_mainFrame->setVisible(TRUE); // Run the main event loop PGEXITCODE exitCode = app.run(); // Free global references PGDECREF(g_textArea); PGDECREF(g_mainFrame); PGDECREF(g_imageAbout); return exitCode; }
Syntax highlighted by Code2HTML, v. 0.8.8 |
Back to PortableGUI