//--------------------------------------------------------------------------- // // Geoworks (R) application software and GEOS (R) operating system // software copyright (C) 1990-1998 Geoworks. All rights reserved. // United States Patents 5327529, 5237651, and 5438662. U.K. Patents // 0375703 and 0631677. German Patents P3854269.2-08 and // 69307728.1-08. French Patents 0375703 and 0631677. Other // international patents pending. // // This software is the confidential and proprietary information of // Geoworks ("Confidential Information"). You shall not disclose // such Confidential Information and shall use it only in accordance // with the terms of the license agreement you entered into with // Geoworks. // // PROJECT: GEOS_SC Documentation // MODULE: Flex UI Chapter // FILE: notepad2.cpp // // VERSION 2.0 // // DESCRIPTION: // // An notepad application that uses a menu to perform file operations // and allows the user to select files from a list. // //------------------------------------------------------------------------- #include // For data types and ec checking. #include // For creating objects in the user interface. #include // For looks in the user interface. #include // For the dialog layouts. #include // For the file store manager. #include // For file operations. #include // For subclassing the resident application. #include // For using localization resources. #include "resource.h" // For the resource strings. #include "notepad2.h" // For the defined methods in the class. // // Strings that are not user-visible and should not be localized. // const TCHAR * const NOTEPAD2APP_NAME = _TEXT("notepad2"); const TCHAR * const NOTEPAD2APP_FILE1_PATH = _TEXT("/int/file1"); const TCHAR * const NOTEPAD2APP_FILE2_PATH = _TEXT("/int/file2"); const TCHAR * const NOTEPAD2APP_FILE3_PATH = _TEXT("/int/file3"); const TCHAR * const NOTEPAD2APP_FILE4_PATH = _TEXT("/int/file4"); // // Our subclass of ResidentApplication, which registers this application // with the system, and provides a way for this app to create its AppBase. // class Notepad2AppResidentApplication : public ResidentApplication { public: Notepad2AppResidentApplication() : ResidentApplication(NOTEPAD2APP_NAME) {}; virtual AppBase *CreateAppBase(void) { return new Notepad2App; } }; static Notepad2AppResidentApplication notepad2App; // // Any attributes that we want to specify about our app - in this case, we // specify the name, but we could also specify an image, maybe a // non-standard stack size or thread priority, etc. // static AppNameAttribute notepad2AppName(¬epad2App, NOTEPAD2APP_APP_TEXT); //--------------------------------------------------------------------------- // Notepad2App::Notepad2App() //--------------------------------------------------------------------------- // // SYNOPSIS: The constructor initializes variables to the initial values. // SCOPE: Public // RETURN: nothing // //--------------------------------------------------------------------------- Notepad2App::Notepad2App() : _notepad2AppMainFrame(NULL), _notepad2AppTextDisplay(NULL), _notepad2AppSaveDialog(NULL), _notepad2AppOpenDialog(NULL), _notepad2AppUIBuilt(FALSE), _notepad2AppDialogOpen(0) { } /* End of Notepad2App::Notepad2App() */ //------------------------------------------------------------------------ // Notepad2App::SetAppContext() //------------------------------------------------------------------------ // // SYNOPSIS: Called when the app is started. Calls the helper function // AttachNotepad2AppUI to build the user interface. // SCOPE: Public // RETURN: nothing // PARAMETERS: [in] context - The application context. // //------------------------------------------------------------------------ void Notepad2App::SetAppContext(const TCHAR *context) { // // Call the helper function to build the UI. // if (!_notepad2AppUIBuilt) { if (AttachNotepad2AppUI() == FAILURE) { EC_WARN("Unable to build Notepad2 application."); Exit(); } else { _notepad2AppUIBuilt = TRUE; } } // // Since we do not use the context parameter, we must pass it to the // USE_IT macro to suppress compiler warnings. // USE_IT(context); } /* End of Notepad2App::SetAppContext() */ //------------------------------------------------------------------------ // Notepad2App::AttachNotepad2AppUI() //------------------------------------------------------------------------ // // SYNOPSIS: Called by SetAppContext to build the user interface. // Attempts to create and add elements of the user interface. // If any element cannot be created or added, FAILURE is // returned and SetAppContext will call the Exit method to // destroy the user interface. // SCOPE: Private // RETURN: SUCCESS or FAILURE // //------------------------------------------------------------------------ Result Notepad2App::AttachNotepad2AppUI(void) { // // Create the main frame for the application // and attempt to add it to the application. // _notepad2AppMainFrame = theUIFactory->CreateFlexFrame(HINT_FRAME_WITH_NO_CLOSE_BUTTON, NOTEPAD2APP_APP_TEXT); if (NULL == _notepad2AppMainFrame) { EC_WARN("Unable to build frame."); return FAILURE; } if (Add(_notepad2AppMainFrame) != SUCCESS) { EC_WARN("Unable to add frame."); delete _notepad2AppMainFrame; return FAILURE; } // // Create a layout for the frame and set it on the frame. // VerticalFlowLayout *frameLayout = new VerticalFlowLayout( NOTEPAD2APP_FRAME_GAP, VerticalFlowLayout::Y_JUSTIFY_CENTER, LayoutManagerInterface::X_ALIGN_LEFT); if (NULL == frameLayout) { EC_WARN("Unable to build layout."); return FAILURE; } _notepad2AppMainFrame->SetLayout(frameLayout); // // Create the menu for the application and attempt to add it // to the frame. // FlexMenu *menu = theUIFactory->CreateFlexMenu(HINT_PULL_DOWN_MENU, NOTEPAD2APP_FILE_MENU_TEXT); if (NULL == menu) { EC_WARN("Unable to create menu."); return FAILURE; } if (_notepad2AppMainFrame->Add(menu) != SUCCESS) { EC_WARN("Unable to add menu."); delete menu; return FAILURE; } // // Create the menu buttons for the menu. // for ( int i = 0; i < 3; i++) { FlexMenuButton *menuButton = theUIFactory->CreateFlexMenuButton(0, NOTEPAD2APP_MENU_ITEMS[i], (MenuItemID) i); if (NULL == menuButton) { EC_WARN("Unable to create button."); return FAILURE; } else { if (menu->Add(menuButton) != SUCCESS) { EC_WARN("Unable to add button."); delete menuButton; return FAILURE; } } } // // Make the application a menu listener. // menu->AddMenuListener(*this); // // Create the dialogs for the application. // if ( CreateDialogUI(NOTEPAD2APP_SAVE_DIALOG_TEXT, &(_notepad2AppSaveDialog)) == FAILURE) { EC_WARN("Unable to create save dialog."); return FAILURE; } if ( CreateDialogUI(NOTEPAD2APP_OPEN_DIALOG_TEXT, &(_notepad2AppOpenDialog)) == FAILURE) { EC_WARN("Unable to create open dialog."); return FAILURE; } // // Create the text display for the application and attempt // to add it to the frame. // _notepad2AppTextDisplay = theUIFactory->CreateFlexTextArea(0); if (NULL == _notepad2AppTextDisplay) { EC_WARN("Unable to create text display."); return FAILURE; } if (_notepad2AppMainFrame->Add(_notepad2AppTextDisplay) != SUCCESS) { EC_WARN("Unable to add text display."); delete _notepad2AppTextDisplay; return FAILURE; } // // Set the attributes of the text display. // _notepad2AppTextDisplay->SetColumns(75); _notepad2AppTextDisplay->SetRows(7); _notepad2AppTextDisplay->SetMaxChars(600); // // Show the frame and return SUCCESS. // _notepad2AppMainFrame->SetVisible(TRUE); return SUCCESS; } /* End of Notepad2App::AttachNotepad2AppUI() */ //----------------------------------------------------------------------- // Notepad2App::CreateDialogUI() //----------------------------------------------------------------------- // // SYNOPSIS: Creates the dialogs for the application. // SCOPE: Private // RETURN: SUCCESS or FAILURE // PARAMETERS The text title of the button and the dialog to create. // //----------------------------------------------------------------------- Result Notepad2App::CreateDialogUI(const TCHAR *title, FlexDialog **dialog) { // // Create a dialog for the application and attempt to add it. // (*dialog) = theUIFactory->CreateFlexDialog(HINT_DIALOG_WITH_NO_CLOSE_BUTTON, title); if (NULL == (*dialog)) { EC_WARN("Unable to create dialog."); return FAILURE; } if (Add(*dialog) != SUCCESS) { EC_WARN("Unable to add dialog."); delete (*dialog); return FAILURE; } // // Create a layout for the dialog. // DialogLayout *dialogLayout = new DialogLayout(); if (NULL == dialogLayout) { EC_WARN("Unable to create dialog layout."); return FAILURE; } (*dialog)->SetLayout(dialogLayout); // // Create a label for the dialog. // FlexLabel *label = theUIFactory->CreateFlexLabel(0, title); if (NULL == label) { EC_WARN("Unable to create label."); return FAILURE; } if ((*dialog)->Add(label) != SUCCESS) { EC_WARN("Unable to add label"); delete label; return FAILURE; } // // Create a list to hold the filenames. // FlexList *list = theUIFactory->CreateFlexList(0, NOTEPAD2APP_LIST_ROWS); if (NULL == list) { EC_WARN("Unable to create list."); return FAILURE; } if ((*dialog)->Add(list) != SUCCESS) { EC_WARN("Unable to add list."); delete list; return FAILURE; } // // Add strings to the list. // if (list->Add(NOTEPAD2APP_FILE1_PATH) == FAILURE) { EC_WARN("Unable to add string to list."); return FAILURE; } if (list->Add(NOTEPAD2APP_FILE2_PATH) == FAILURE) { EC_WARN("Unable to add string to list."); return FAILURE; } if (list->Add(NOTEPAD2APP_FILE3_PATH) == FAILURE) { EC_WARN("Unable to add string to list."); return FAILURE; } if (list->Add(NOTEPAD2APP_FILE4_PATH) == FAILURE) { EC_WARN("Unable to add string to list."); return FAILURE; } // // Add a listener to the system and return SUCCESS. // if (list->AddItemListener(*this) != SUCCESS) { EC_WARN("Unable to add item listener."); delete list; } return SUCCESS; } /* End of Notepad2App::CreateDialogUI() */ //------------------------------------------------------------------------------- // Notepad2App::MenuItemChosen(MenuEvent& event ) //------------------------------------------------------------------------------- // // SYNOPSIS: Handles the menu events for deciding which file operation // the user wants to execute. If the user elects to save or open // a file, the appropriate dialog will open. // SCOPE: Public // RETURN: nothing // //------------------------------------------------------------------------------- void Notepad2App::MenuItemChosen(MenuEvent& event ) { // // Get the id for the menu item chosen. // uint32 id = (uint32)event._menuItemID; // // As long as there is not an open dialog, // either make a New file, Save a file, or Open a file. // if (_notepad2AppDialogOpen == 0) { switch (id) { case NOTEPAD2APP_NEW_MENU_ITEM: _notepad2AppTextDisplay->SetText(_TEXT("")); break; case NOTEPAD2APP_SAVE_MENU_ITEM: _notepad2AppDialogOpen = id; _notepad2AppSaveDialog->SetVisible(TRUE); break; case NOTEPAD2APP_OPEN_MENU_ITEM: _notepad2AppDialogOpen = id; _notepad2AppOpenDialog->SetVisible(TRUE); break; } } } /* End of Notepad2App::MenuItemChosen() */ //------------------------------------------------------------------------------- // Notepad2App::ItemStateChanged(ItemEvent& event ) //------------------------------------------------------------------------------- // // SYNOPSIS: Handles the item events for determining which file the users // wants to either save to or read from. // SCOPE: Public // RETURN: nothing // //------------------------------------------------------------------------------- void Notepad2App::ItemStateChanged(ItemEvent& event ) { // // Create a file pointer for SAVE and OPEN, // as well as a string for the filename. // File *myFile = NULL; const TCHAR *filename = NULL; TCHAR *textBuffer; int32 bufferSize = 0; // // Get the list and its index. // FlexList *list = (FlexList *)event.GetSource(); uint32 index = event.GetIndex(); // // Set the filename depending on the index. // switch (index) { case 0: filename = NOTEPAD2APP_FILE1_PATH; break; case 1: filename = NOTEPAD2APP_FILE2_PATH; break; case 2: filename = NOTEPAD2APP_FILE3_PATH; break; case 3: filename = NOTEPAD2APP_FILE4_PATH; break; } // // Check if SAVE was clicked. // if (_notepad2AppDialogOpen == NOTEPAD2APP_SAVE_MENU_ITEM) { // // Set the size of the buffer to read. // bufferSize = (_notepad2AppTextDisplay->GetCharCount() + 1); textBuffer = new TCHAR[bufferSize]; // // Store the contents of the buffer. // _notepad2AppTextDisplay->GetText(textBuffer, bufferSize); // // Open the file CREATE and READ_WRITE // myFile = theFileStoreManager.Open(filename, O_CREAT | O_RDWR ); if (myFile != NULL) { // // Write the contents of the buffer to the file // and close the file. // myFile->Write((uint8 *)textBuffer, bufferSize * sizeof(TCHAR)); myFile->SetSize(bufferSize * sizeof(TCHAR)); } else { _notepad2AppTextDisplay->SetText(NOTEPAD2APP_ERROR); } // // Delete the buffer, close the file and the dialog. // delete [] textBuffer; myFile->Close(); _notepad2AppSaveDialog->SetVisible(FALSE); } // // Check if OPEN was clicked. // else if (_notepad2AppDialogOpen == NOTEPAD2APP_OPEN_MENU_ITEM) { // // Open the file READ_ONLY and read the contents into the buffer, // closing the file when done. // myFile = theFileStoreManager.Open(filename, O_RDONLY ); if (myFile != NULL) { myFile->GetSize(&bufferSize); textBuffer = new TCHAR[bufferSize]; // // Attempt to read the buffer and copy the text to the text area. // if (myFile->Read((uint8*)textBuffer, bufferSize) != bufferSize) { _notepad2AppTextDisplay->SetText(NOTEPAD2APP_ERROR); } _notepad2AppTextDisplay->SetText(textBuffer); myFile->Close(); delete [] textBuffer; } else { _notepad2AppTextDisplay->SetText(NOTEPAD2APP_ERROR); } // // Close the dialog. // _notepad2AppOpenDialog->SetVisible(FALSE); } // // Unselect any list items and reset the file pointer. // list->Deselect(index); myFile = NULL; // // Mark the dialog box as unopened. // _notepad2AppDialogOpen = 0; } /* End of Notepad2App::ItemStateChanged() */ //--------------------------------------------------------------------------- // Notepad2App::Exit() //--------------------------------------------------------------------------- // // SYNOPSIS: Use Exit to clean up when the application quits. This includes // deleting any elements of the user interface, such as layouts, // that were not created by theUIFactory. // SCOPE: Public // RETURN: nothing // //--------------------------------------------------------------------------- void Notepad2App::Exit(void) { // // Delete the layouts for the main frame and // the dialogs. // if (_notepad2AppMainFrame) { delete _notepad2AppMainFrame->RemoveLayout(); } if (_notepad2AppSaveDialog) { delete _notepad2AppSaveDialog->RemoveLayout(); } if (_notepad2AppOpenDialog) { delete _notepad2AppOpenDialog->RemoveLayout(); } // // Set the boolean for the application. // _notepad2AppUIBuilt = FALSE; AppBase::Exit(); } /* End of Notepad2App::Exit() */