[haiku-commits] r35221 - in haiku/trunk/src/apps: . readonlybootprompt

  • From: superstippi@xxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Thu, 21 Jan 2010 15:41:59 +0100 (CET)

Author: stippi
Date: 2010-01-21 15:41:58 +0100 (Thu, 21 Jan 2010)
New Revision: 35221
Changeset: http://dev.haiku-os.org/changeset/35221/haiku

Added:
   haiku/trunk/src/apps/readonlybootprompt/
   haiku/trunk/src/apps/readonlybootprompt/BootPrompt.cpp
   haiku/trunk/src/apps/readonlybootprompt/BootPrompt.h
   haiku/trunk/src/apps/readonlybootprompt/BootPrompt.rdef
   haiku/trunk/src/apps/readonlybootprompt/BootPromptWindow.cpp
   haiku/trunk/src/apps/readonlybootprompt/BootPromptWindow.h
   haiku/trunk/src/apps/readonlybootprompt/Jamfile
Modified:
   haiku/trunk/src/apps/Jamfile
Log:
Added application which is supposed to replace the "Do you wish to run the
Installer or continue booting to the Desktop" alert that pops up on CD boots.
It allows to set the language and keymap as the very first thing before a Haiku
installation. (Aside from replacing the alert.) Everything tested and working,
I just need to test integration in the Bootscript.


Modified: haiku/trunk/src/apps/Jamfile
===================================================================
--- haiku/trunk/src/apps/Jamfile        2010-01-21 14:39:43 UTC (rev 35220)
+++ haiku/trunk/src/apps/Jamfile        2010-01-21 14:41:58 UTC (rev 35221)
@@ -43,6 +43,7 @@
 HaikuSubInclude powerstatus ;
 HaikuSubInclude processcontroller ;
 HaikuSubInclude pulse ;
+HaikuSubInclude readonlybootprompt ;
 HaikuSubInclude remotedesktop ;
 HaikuSubInclude resedit ;
 HaikuSubInclude screenshot ;

Added: haiku/trunk/src/apps/readonlybootprompt/BootPrompt.cpp
===================================================================
--- haiku/trunk/src/apps/readonlybootprompt/BootPrompt.cpp                      
        (rev 0)
+++ haiku/trunk/src/apps/readonlybootprompt/BootPrompt.cpp      2010-01-21 
14:41:58 UTC (rev 35221)
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2010, Stephan Aßmus <superstippi@xxxxxx>
+ * All rights reserved. Distributed under the terms of the MIT License.
+ */
+
+#include "BootPrompt.h"
+
+#include <stdlib.h>
+
+#include <AboutWindow.h>
+#include <Locale.h>
+
+#include "BootPromptWindow.h"
+
+
+int
+main(int, char **)
+{
+       BootPromptApp app;
+       app.Run();
+       return 0;
+}
+
+
+// #pragma mark -
+
+
+const char* kAppSignature = "application/x-vnd.Haiku-ReadOnlyBootPrompt";
+
+
+BootPromptApp::BootPromptApp()
+       :
+       BApplication(kAppSignature)
+{
+}
+
+
+void
+BootPromptApp::MessageReceived(BMessage* message)
+{
+       switch (message->what) {
+               case MSG_BOOT_DESKTOP:
+                       // TODO: Exit with some value that the Bootscript can 
deal with.
+                       exit(1);
+                       break;
+               case MSG_RUN_INSTALLER:
+                       // TODO: Exit with some value that the Bootscript can 
deal with.
+                       exit(0);
+                       break;
+
+               default:
+                       BApplication::MessageReceived(message);
+       }
+}
+
+
+void
+BootPromptApp::AboutRequested()
+{
+       const char* kAuthors[] = {
+               "Stephan Aßmus",
+               NULL
+       };
+
+       BAboutWindow* aboutWindow = new BAboutWindow("ReadOnlyBootPrompt", 2010,
+               kAuthors);
+
+       aboutWindow->Show();
+}
+
+
+void
+BootPromptApp::ReadyToRun()
+{
+       // Prompt the user to select his preferred language.
+       new BootPromptWindow();
+}
+

Added: haiku/trunk/src/apps/readonlybootprompt/BootPrompt.h
===================================================================
--- haiku/trunk/src/apps/readonlybootprompt/BootPrompt.h                        
        (rev 0)
+++ haiku/trunk/src/apps/readonlybootprompt/BootPrompt.h        2010-01-21 
14:41:58 UTC (rev 35221)
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2010, Stephan Aßmus <superstippi@xxxxxx>.
+ * All rights reserved. Distributed under the terms of the MIT License.
+ */
+#ifndef BOOT_PROMPT_APP_H
+#define BOOT_PROMPT_APP_H
+
+#include <Application.h>
+
+
+enum {
+       MSG_BOOT_DESKTOP        = 'dktp',
+       MSG_RUN_INSTALLER       = 'inst'
+};
+
+extern const char* kAppSignature;
+
+
+class BootPromptApp : public BApplication {
+public:
+                                                               BootPromptApp();
+
+       virtual void                            MessageReceived(BMessage* 
message);
+       virtual void                            AboutRequested();
+       virtual void                            ReadyToRun();
+};
+
+#endif // BOOT_PROMPT_APP_H

Added: haiku/trunk/src/apps/readonlybootprompt/BootPrompt.rdef
===================================================================
--- haiku/trunk/src/apps/readonlybootprompt/BootPrompt.rdef                     
        (rev 0)
+++ haiku/trunk/src/apps/readonlybootprompt/BootPrompt.rdef     2010-01-21 
14:41:58 UTC (rev 35221)
@@ -0,0 +1,17 @@
+
+resource app_signature "application/x-vnd.Haiku-ReadOnlyBootPrompt";
+
+resource app_version {
+       major  = 1,
+       middle = 0,
+       minor  = 0,
+
+       variety = B_APPV_BETA,
+       internal = 0,
+
+       short_info = "ReadOnlyBootPrompt",
+       long_info  = "ReadOnlyBootPrompt ©2010 The Haiku Project"
+};
+
+resource app_flags B_EXCLUSIVE_LAUNCH;
+

Added: haiku/trunk/src/apps/readonlybootprompt/BootPromptWindow.cpp
===================================================================
--- haiku/trunk/src/apps/readonlybootprompt/BootPromptWindow.cpp                
                (rev 0)
+++ haiku/trunk/src/apps/readonlybootprompt/BootPromptWindow.cpp        
2010-01-21 14:41:58 UTC (rev 35221)
@@ -0,0 +1,398 @@
+/*
+ * Copyright 2010, Stephan Aßmus <superstippi@xxxxxx>
+ * All rights reserved. Distributed under the terms of the MIT License.
+ */
+
+#include "BootPromptWindow.h"
+
+#include <stdio.h>
+
+#include <Button.h>
+#include <ControlLook.h>
+#include <Directory.h>
+#include <Entry.h>
+#include <Font.h>
+#include <FindDirectory.h>
+#include <File.h>
+#include <GroupLayoutBuilder.h>
+#include <ListView.h>
+#include <Locale.h>
+#include <LocaleRoster.h>
+#include <Path.h>
+#include <ScrollView.h>
+#include <SeparatorView.h>
+#include <StringItem.h>
+#include <StringView.h>
+#include <TextView.h>
+
+#include "BootPrompt.h"
+#include "Keymap.h"
+#include "KeymapListItem.h"
+
+
+enum {
+       MSG_LANGUAGE_SELECTED   = 'lngs',
+       MSG_KEYMAP_SELECTED             = 'kmps'
+};
+
+#undef TR_CONTEXT
+#define TR_CONTEXT "BootPromptWindow"
+
+
+class LanguageItem : public BStringItem {
+public:
+       LanguageItem(const char* label, const char* language)
+               :
+               BStringItem(label),
+               fLanguage(language)
+       {
+       }
+
+       const char* Language() const
+       {
+               return fLanguage.String();
+       }
+
+private:
+       BString fLanguage;
+};
+
+
+BootPromptWindow::BootPromptWindow()
+       :
+       BWindow(BRect(0, 0, 450, 380), "",
+               B_TITLED_WINDOW, B_NOT_ZOOMABLE | B_NOT_MINIMIZABLE | 
B_NOT_CLOSABLE
+                       | B_AUTO_UPDATE_SIZE_LIMITS)
+{
+       // TODO: Remove once BLocalRoster is fixed.
+       be_locale_roster->GetInstalledLanguages(&fInstalledLanguages);
+
+       fInfoTextView = new BTextView("info", be_plain_font, NULL, B_WILL_DRAW);
+       fInfoTextView->SetInsets(10, 10, 10, 10);
+       fInfoTextView->MakeEditable(false);
+       fInfoTextView->MakeSelectable(false);
+
+       BScrollView* infoScrollView = new BScrollView("infoScroll",
+               fInfoTextView, B_WILL_DRAW, false, true);
+
+       fDesktopButton = new BButton("", new BMessage(MSG_BOOT_DESKTOP));
+       fDesktopButton->SetTarget(be_app);
+       fDesktopButton->MakeDefault(true);
+
+       fInstallerButton = new BButton("", new BMessage(MSG_RUN_INSTALLER));
+       fInstallerButton->SetTarget(be_app);
+
+       fLanguagesLabelView = new BStringView("languagesLabel", "");
+       fLanguagesLabelView->SetFont(be_bold_font);
+       fLanguagesLabelView->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED,
+               B_SIZE_UNSET));
+
+       fKeymapsLabelView = new BStringView("keymapsLabel", "");
+       fKeymapsLabelView->SetFont(be_bold_font);
+       fKeymapsLabelView->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED,
+               B_SIZE_UNSET));
+
+       fLanguagesListView = new BListView();
+       BScrollView* languagesScrollView = new BScrollView("languagesScroll",
+               fLanguagesListView, B_WILL_DRAW, false, true);
+
+       fKeymapsListView = new BListView();
+       BScrollView* keymapsScrollView = new BScrollView("keymapsScroll",
+               fKeymapsListView, B_WILL_DRAW, false, true);
+
+       _InitCatalog(false);
+       _UpdateStrings();
+
+       float spacing = be_control_look->DefaultItemSpacing();
+
+       SetLayout(new BGroupLayout(B_HORIZONTAL));
+       AddChild(BGroupLayoutBuilder(B_VERTICAL)
+               .Add(BGroupLayoutBuilder(B_VERTICAL, spacing)
+                       .Add(infoScrollView)
+                       .Add(BGroupLayoutBuilder(B_HORIZONTAL, spacing)
+                               .Add(BGroupLayoutBuilder(B_VERTICAL, spacing)
+                                       .Add(fLanguagesLabelView)
+                                       .Add(languagesScrollView)
+                               )
+                               .Add(BGroupLayoutBuilder(B_VERTICAL, spacing)
+                                       .Add(fKeymapsLabelView)
+                                       .Add(keymapsScrollView)
+                               )
+                       )
+                       .SetInsets(spacing, spacing, spacing, spacing)
+               )
+               .Add(new BSeparatorView(B_HORIZONTAL))
+               .Add(BGroupLayoutBuilder(B_HORIZONTAL, spacing)
+                       .AddGlue()
+                       .Add(fInstallerButton)
+                       .Add(fDesktopButton)
+                       .SetInsets(spacing, spacing, spacing, spacing)
+               )
+       );
+
+       CenterOnScreen();
+       Show();
+}
+
+
+void
+BootPromptWindow::MessageReceived(BMessage* message)
+{
+       switch (message->what) {
+               case MSG_LANGUAGE_SELECTED:
+                       if (BListItem* item = fLanguagesListView->ItemAt(
+                               fLanguagesListView->CurrentSelection(0))) {
+                               LanguageItem* languageItem = 
dynamic_cast<LanguageItem*>(item);
+                               BMessage preferredLanguages;
+                               preferredLanguages.AddString("language",
+                                       languageItem->Language());
+                               
be_locale_roster->SetPreferredLanguages(&preferredLanguages);
+                               _InitCatalog(true);
+                       }
+                       // Calling it here is a cheap way of preventing the 
user to have
+                       // no item selected. Always the current item will be 
selected.
+                       _UpdateStrings();
+                       break;
+
+               case MSG_KEYMAP_SELECTED:
+                       _StoreKeymap();
+                       break;
+
+               default:
+                       BWindow::MessageReceived(message);
+       }
+}
+
+
+void
+BootPromptWindow::_InitCatalog(bool saveSettings)
+{
+       // Initilialize the Locale Kit
+       // TODO: The below code is a work-around for not being able to
+       // call GetAppCatalog() more than once.
+       be_catalog = be_app_catalog = NULL;
+       // NOTE: be_catalog and be_app_catalog will point fo &fCatalog!
+
+       be_locale->GetAppCatalog(&fCatalog);
+
+       // Generate a settings file
+       // TODO: This should not be necessary.
+       // be_locale_roster->SetPreferredLanguages() should take care of things
+       if (!saveSettings)
+               return;
+
+       BPath path;
+       if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK
+               || path.Append("Locale settings") != B_OK) {
+               return;
+       }
+
+       BMessage settings;
+
+       BFile file;
+       if (file.SetTo(path.Path(), B_READ_ONLY) == B_OK)
+               settings.Unflatten(&file);
+
+       BString language;
+       if (fCatalog.GetLanguage(&language) == B_OK) {
+               settings.RemoveName("language");
+               settings.AddString("language", language.String());
+       }
+
+       settings.RemoveName("country");
+       BCountry country(language.String(), language.ToUpper());
+       settings.AddString("country", country.Code());
+
+       if (file.SetTo(path.Path(), B_CREATE_FILE | B_ERASE_FILE | B_WRITE_ONLY)
+                       != B_OK
+               || settings.Flatten(&file) != B_OK) {
+               fprintf(stderr, "Failed to write Local Kit settings!\n");
+       }
+}
+
+
+void
+BootPromptWindow::_UpdateStrings()
+{
+       SetTitle(TR("Welcome to Haiku"));
+
+       const char* infoText = TR(
+               "Welcome to Haiku!\n\n"
+
+               "Do you wish to want to run the Installer or continue booting "
+               "to the Desktop?\n\n"
+
+               "Please select your preferred language and keyboard layout from 
"
+               "the list below."
+       );
+
+       fInfoTextView->SetText(infoText);
+
+       fDesktopButton->SetLabel(TR("Desktop"));
+       fInstallerButton->SetLabel(TR("Installer"));
+
+       fLanguagesLabelView->SetText(TR("Language"));
+       fKeymapsLabelView->SetText(TR("Keymap"));
+
+       _PopulateLanguages();
+       _PopulateKeymaps();
+}
+
+
+void
+BootPromptWindow::_PopulateLanguages()
+{
+       // Disable sending the selection message while we change the selection.
+       fLanguagesListView->SetSelectionMessage(NULL);
+
+       // Clear the list view first
+       while (BListItem* item = fLanguagesListView->RemoveItem(
+                       fLanguagesListView->CountItems() - 1)) {
+               delete item;
+       }
+
+       // Get current first preferred language of the user
+       BMessage preferredLanguages;
+       be_locale_roster->GetPreferredLanguages(&preferredLanguages);
+       const char* firstPreferredLanguage;
+       if (preferredLanguages.FindString("language", &firstPreferredLanguage)
+                       != B_OK) {
+               // Fall back to built-in language of this application.
+               firstPreferredLanguage = "en";
+       }
+
+// TODO: Use this API instead once it's ready.
+//     BMessage installedCatalogs;
+//     be_locale_roster->GetInstalledCatalogs(&installedCatalogs);
+//     installedCatalogs.PrintToStream();
+
+// TODO: BLocaleRoster uses static variables!! Fix this! Or else one can only
+// call this once!
+//     // Get the list of all known languages
+//     BMessage installedLanguages;
+//     be_locale_roster->GetInstalledLanguages(&installedLanguages);
+
+       // Try to instantiate a BCatalog for each language, it will only work
+       // for translations of this application. So the list of languages will 
be
+       //  limited to catalogs written for this application, which is on 
purpose!
+       const char* languageString;
+       for (int32 i = 0;
+               fInstalledLanguages.FindString("langs", i, &languageString) == 
B_OK;
+               i++) {
+               BCatalog catalog("x-vnd.Haiku-ReadOnlyBootPrompt", 
languageString);
+               if (catalog.InitCheck() == B_OK) {
+                       BLanguage* language;
+                       if (be_locale_roster->GetLanguage(&language,
+                                       BString(languageString)) == B_OK) {
+                               BString name;
+                               language->GetName(&name);
+                               LanguageItem* item = new 
LanguageItem(name.String(),
+                                       languageString);
+                               fLanguagesListView->AddItem(item);
+                               // Select this item if it is the first 
preferred language
+                               if (strcmp(firstPreferredLanguage, 
languageString) == 0) {
+                                       fLanguagesListView->Select(
+                                               
fLanguagesListView->CountItems() - 1);
+                               }
+                       } else
+                               printf("failed to get BLanguage for %s\n", 
languageString);
+               }
+       }
+
+       // Re-enable sending the selection message.
+       fLanguagesListView->SetSelectionMessage(
+               new BMessage(MSG_LANGUAGE_SELECTED));
+}
+
+
+void
+BootPromptWindow::_PopulateKeymaps()
+{
+       // Disable sending the selection message while we change the selection.
+       fKeymapsListView->SetSelectionMessage(NULL);
+
+       // Clean the list view first
+       while (BListItem* item = fKeymapsListView->RemoveItem(
+                       fKeymapsListView->CountItems() - 1)) {
+               delete item;
+       }
+
+       // Get the name of the current keymap, so we can mark the correct entry
+       // in the list view.
+       BString currentKeymapName;
+       entry_ref ref;
+       if (_GetCurrentKeymapRef(ref) == B_OK) {
+               BNode node(&ref);
+               node.ReadAttrString("keymap:name", &currentKeymapName);
+       }
+
+       // TODO: common keymaps!
+       BPath path;
+       if (find_directory(B_SYSTEM_DATA_DIRECTORY, &path) != B_OK
+               || path.Append("Keymaps") != B_OK) {
+               return;
+       }
+
+       // Populate the list
+       BDirectory directory;
+       if (directory.SetTo(path.Path()) == B_OK) {
+               while (directory.GetNextRef(&ref) == B_OK) {
+                       fKeymapsListView->AddItem(new KeymapListItem(ref));
+                       if (currentKeymapName == ref.name)
+                               
fKeymapsListView->Select(fKeymapsListView->CountItems() - 1);
+               }
+       }
+
+       fKeymapsListView->ScrollToSelection();
+
+       // Re-enable sending the selection message.
+       fKeymapsListView->SetSelectionMessage(
+               new BMessage(MSG_KEYMAP_SELECTED));
+}
+
+
+void
+BootPromptWindow::_StoreKeymap() const
+{
+       KeymapListItem* item = dynamic_cast<KeymapListItem*>(
+               
fKeymapsListView->ItemAt(fKeymapsListView->CurrentSelection(0)));
+       if (item == NULL)
+               return;
+
+       // Load and use the new keymap
+       Keymap keymap;
+       if (keymap.Load(item->EntryRef()) != B_OK) {
+               fprintf(stderr, "Failed to load new keymap file (%s).\n",
+                       item->EntryRef().name);
+               return;
+       }
+
+       // Get entry_ref to the Key_map file in the user settings.
+       entry_ref ref;
+       if (_GetCurrentKeymapRef(ref) != B_OK) {
+               fprintf(stderr, "Failed to get ref to user keymap file.\n");
+               return;
+       }
+
+       if (keymap.Save(ref) != B_OK) {
+               fprintf(stderr, "Failed to save new keymap file (%s).\n",
+                       item->EntryRef().name);
+               return;
+       }
+
+       keymap.Use();
+}
+
+
+status_t
+BootPromptWindow::_GetCurrentKeymapRef(entry_ref& ref) const
+{
+       BPath path;
+       if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK
+               || path.Append("Key_map") != B_OK) {
+               return B_ERROR;
+       }
+
+       return get_ref_for_path(path.Path(), &ref);
+}
+

Added: haiku/trunk/src/apps/readonlybootprompt/BootPromptWindow.h
===================================================================
--- haiku/trunk/src/apps/readonlybootprompt/BootPromptWindow.h                  
        (rev 0)
+++ haiku/trunk/src/apps/readonlybootprompt/BootPromptWindow.h  2010-01-21 
14:41:58 UTC (rev 35221)
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2010, Stephan Aßmus <superstippi@xxxxxx>.
+ * All rights reserved. Distributed under the terms of the MIT License.
+ */
+#ifndef BOOT_PROMPT_WINDOW_H
+#define BOOT_PROMPT_WINDOW_H
+
+#include <Catalog.h>
+#include <Message.h>
+#include <Window.h>
+
+class BButton;
+class BListView;
+class BStringView;
+class BTextView;
+
+
+class BootPromptWindow : public BWindow {
+public:
+                                                               
BootPromptWindow();
+
+       virtual void                            MessageReceived(BMessage* 
message);
+
+private:
+                       void                            _InitCatalog(bool 
saveSettings);
+                       void                            _UpdateStrings();
+                       void                            _PopulateLanguages();
+                       void                            _PopulateKeymaps();
+                       void                            _StoreKeymap() const;
+                       status_t                        
_GetCurrentKeymapRef(entry_ref& ref) const;
+
+private:
+                       BCatalog                        fCatalog;
+                       BTextView*                      fInfoTextView;
+                       BStringView*            fLanguagesLabelView;
+                       BListView*                      fLanguagesListView;
+                       BStringView*            fKeymapsLabelView;
+                       BListView*                      fKeymapsListView;
+                       BButton*                        fDesktopButton;
+                       BButton*                        fInstallerButton;
+
+       // TODO: Should not be needed, see TODO in _PopulateLanguages()
+                       BMessage                        fInstalledLanguages;
+};
+
+#endif // BOOT_PROMPT_WINDOW_H

Added: haiku/trunk/src/apps/readonlybootprompt/Jamfile
===================================================================
--- haiku/trunk/src/apps/readonlybootprompt/Jamfile                             
(rev 0)
+++ haiku/trunk/src/apps/readonlybootprompt/Jamfile     2010-01-21 14:41:58 UTC 
(rev 35221)
@@ -0,0 +1,24 @@
+SubDir HAIKU_TOP src apps readonlybootprompt ;
+
+UsePrivateHeaders interface shared ;
+
+SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src preferences keymap ] ;
+
+Application ReadOnlyBootPrompt :
+       BootPrompt.cpp
+       BootPromptWindow.cpp
+       Keymap.cpp
+       KeymapListItem.cpp
+       : be libshared.a $(TARGET_LIBSTDC++) liblocale.so
+       : BootPrompt.rdef
+;
+
+DoCatalogs ReadOnlyBootPrompt :
+       x-vnd.Haiku-ReadOnlyBootPrompt
+       :
+       BootPrompt.cpp
+       BootPromptWindow.cpp
+       : en.catalog
+       : de.catkeys
+;
+


Other related posts: