[haiku-commits] r36727 - in haiku/trunk: headers/os/locale src/kits/locale src/preferences/locale

  • From: axeld@xxxxxxxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Fri, 7 May 2010 19:38:41 +0200 (CEST)

Author: axeld
Date: 2010-05-07 19:38:40 +0200 (Fri, 07 May 2010)
New Revision: 36727
Changeset: http://dev.haiku-os.org/changeset/36727/haiku
Ticket: http://dev.haiku-os.org/ticket/5896

Modified:
   haiku/trunk/headers/os/locale/Language.h
   haiku/trunk/headers/os/locale/LocaleRoster.h
   haiku/trunk/src/kits/locale/Language.cpp
   haiku/trunk/src/kits/locale/LocaleRoster.cpp
   haiku/trunk/src/preferences/locale/Jamfile
   haiku/trunk/src/preferences/locale/LanguageListView.cpp
   haiku/trunk/src/preferences/locale/LanguageListView.h
   haiku/trunk/src/preferences/locale/Locale.h
   haiku/trunk/src/preferences/locale/LocaleWindow.cpp
   haiku/trunk/src/preferences/locale/LocaleWindow.h
Log:
* Changed BLocaleRoster::GetLanguage() to a signature that makes more sense,
  and looks more like the rest of the API.
* Also, it will now return an appropriate error code if the language couldn't
  be allocated (anything else than B_OK is an improvement :-)).
* Several changes in BLanguage:
  - GetName() now gets a BString reference, also
  - it now returns the name in its own language, ie. for German this would
    always be "deutsch", no matter the current language settings, and finally,
  - it now empties the string it gets before adding the name.
  - added GetTranslatedName() that behaves like the previous version.
  - added const where it made sense (ie. almost everywhere).
  - Code() now returns the code of the language only.
  - ID() now returns the full ID of this language, ie. including country,
    variant, and keywords if any.
  - added Country(), and Variant().
  - renamed IsCountry() to IsCountrySpecific().
  - added IsVariant().
* Cleaned up Language.h, minor cleanup in LocaleRoster.cpp.
* Removed the whole move item logic from LanguageListView; while this was not
  only spaghetti code, it doesn't make much sense in the first place.
* Instead of removing stuff from the left, and even worse, moving all countries
  for a language even if only one had been dragged, we now only mark the items
  that are already in the preferred list, and only those.
* Fixed various mixups of FullList*() vs. *() methods that could lead to things
  like bug #5896.
* Pressing the delete key in the preferred list view will now remove the
  language.
* Moved LocaleWindow specific message constants to LocaleWindow.cpp; Locale.h
  is supposed to contain application wide constants.
* The drop logic is now in LocaleWindow.
* We now make sure that each base language can only be in the list once.
* Lots of cleanup, even though I mostly replaced spaghettie code with different
  looking spaghettie code - still, I think things have slightly improved.


Modified: haiku/trunk/headers/os/locale/Language.h
===================================================================
--- haiku/trunk/headers/os/locale/Language.h    2010-05-07 17:30:31 UTC (rev 
36726)
+++ haiku/trunk/headers/os/locale/Language.h    2010-05-07 17:38:40 UTC (rev 
36727)
@@ -1,16 +1,14 @@
 /*
-** Copyright 2003, Haiku, Inc.
-** Distributed under the terms of the MIT License.
-*/
-
-
+ * Copyright 2003-2010, Haiku, Inc.
+ * Distributed under the terms of the MIT License.
+ */
 #ifndef _LANGUAGE_H_
 #define _LANGUAGE_H_
 
 
+#include <LocaleStrings.h>
 #include <String.h>
 #include <SupportDefs.h>
-#include <LocaleStrings.h>
 
 
 // We must not include the icu headers in there as it could mess up binary
@@ -28,29 +26,37 @@
 
 
 class BLanguage {
-       public:
-               ~BLanguage();
+public:
+                                                               ~BLanguage();
 
-               // language name, e.g. "english", "deutsch"
-               status_t GetName(BString* name);
-               // ISO-639 language code, e.g. "en", "de"
-               const char* Code();
-               bool    IsCountry();
+                       status_t                        GetName(BString& name) 
const;
+                       status_t                        
GetTranslatedName(BString& name) const;
 
-               uint8 Direction() const;
+                       // ISO-639 language code, e.g. "en", "de"
+                       const char*                     Code() const;
+                       const char*                     Country() const;
+                       const char*                     Variant() const;
+                       const char*                     ID() const;
 
-               // see definitions below
-               const char *GetString(uint32 id) const;
+                       bool                            IsCountrySpecific() 
const;
+                       bool                            IsVariant() const;
 
-       private:
-               friend class BLocaleRoster;
+                       uint8                           Direction() const;
 
-               BLanguage(const char *language);
-               void Default();
+                       // see definitions below
+                       const char*                     GetString(uint32 id) 
const;
 
-               char    *fStrings[B_NUM_LANGUAGE_STRINGS];
-               uint8   fDirection;
-               icu_4_2::Locale* fICULocale;
+private:
+                       friend class BLocaleRoster;
+
+                                                               BLanguage(const 
char *language);
+                       void                            Default();
+
+private:
+                       char*                           
fStrings[B_NUM_LANGUAGE_STRINGS];
+                       uint8                           fDirection;
+                       icu_4_2::Locale*        fICULocale;
 };
 
-#endif /* _LANGUAGE_H_ */
+
+#endif // _LANGUAGE_H_

Modified: haiku/trunk/headers/os/locale/LocaleRoster.h
===================================================================
--- haiku/trunk/headers/os/locale/LocaleRoster.h        2010-05-07 17:30:31 UTC 
(rev 36726)
+++ haiku/trunk/headers/os/locale/LocaleRoster.h        2010-05-07 17:38:40 UTC 
(rev 36727)
@@ -1,3 +1,7 @@
+/*
+ * Copyright 2003-2010, Haiku. All rights reserved.
+ * Distributed under the terms of the MIT license.
+ */
 #ifndef _LOCALE_ROSTER_H_
 #define _LOCALE_ROSTER_H_
 
@@ -17,7 +21,7 @@
 
 namespace BPrivate {
        class EditableCatalog;
-};
+}
 
 enum {
        B_LOCALE_CHANGED        = '_LCC',
@@ -25,7 +29,6 @@
 
 
 class BLocaleRoster {
-
        public:
                BLocaleRoster();
                ~BLocaleRoster();
@@ -42,7 +45,8 @@
                status_t GetDefaultCountry(BCountry **) const;
                void SetDefaultCountry(BCountry *) const;
 
-               status_t GetLanguage(BLanguage** language, BString 
languageCode) const;
+                       status_t                        GetLanguage(const char* 
languageCode,
+                                                                       
BLanguage** _language) const;
 
                status_t GetPreferredLanguages(BMessage *) const;
                status_t SetPreferredLanguages(BMessage *);

Modified: haiku/trunk/src/kits/locale/Language.cpp
===================================================================
--- haiku/trunk/src/kits/locale/Language.cpp    2010-05-07 17:30:31 UTC (rev 
36726)
+++ haiku/trunk/src/kits/locale/Language.cpp    2010-05-07 17:38:40 UTC (rev 
36727)
@@ -80,10 +80,7 @@
 };
 
 
-//     #pragma mark -
-
-
-BLanguage::BLanguage(const char *language)
+BLanguage::BLanguage(const char* language)
        :
        fDirection(B_LEFT_TO_RIGHT)
 {
@@ -123,10 +120,11 @@
 }
 
 
-const char *
+const char*
 BLanguage::GetString(uint32 id) const
 {
-       if (id < B_LANGUAGE_STRINGS_BASE || id > B_LANGUAGE_STRINGS_BASE + 
B_NUM_LANGUAGE_STRINGS)
+       if (id < B_LANGUAGE_STRINGS_BASE
+               || id > B_LANGUAGE_STRINGS_BASE + B_NUM_LANGUAGE_STRINGS)
                return NULL;
 
        return fStrings[id - B_LANGUAGE_STRINGS_BASE];
@@ -134,30 +132,84 @@
 
 
 status_t
-BLanguage::GetName(BString* name)
+BLanguage::GetName(BString& name) const
 {
+       UnicodeString string;
+       fICULocale->getDisplayName(*fICULocale, string);
+
+       name.Truncate(0);
+       BStringByteSink converter(&name);
+       string.toUTF8(converter);
+
+       return B_OK;
+}
+
+
+status_t
+BLanguage::GetTranslatedName(BString& name) const
+{
        BMessage preferredLanguage;
        be_locale_roster->GetPreferredLanguages(&preferredLanguage);
+
        BString appLanguage;
-       
        preferredLanguage.FindString("language", 0, &appLanguage);
-       
-       UnicodeString s;
-       fICULocale->getDisplayName(Locale(appLanguage), s);
-       BStringByteSink converter(name);
-       s.toUTF8(converter);
+
+       UnicodeString string;
+       fICULocale->getDisplayName(Locale(appLanguage), string);
+
+       name.Truncate(0);
+       BStringByteSink converter(&name);
+       string.toUTF8(converter);
+
        return B_OK;
 }
 
+
 const char*
-BLanguage::Code()
+BLanguage::Code() const
 {
        return fICULocale->getLanguage();
 }
 
 
+const char*
+BLanguage::Country() const
+{
+       const char* country = fICULocale->getCountry();
+       if (country == NULL || country[0] == '\0')
+               return NULL;
+
+       return country;
+}
+
+
+const char*
+BLanguage::Variant() const
+{
+       const char* variant = fICULocale->getVariant();
+       if (variant == NULL || variant[0] == '\0')
+               return NULL;
+
+       return variant;
+}
+
+
+const char*
+BLanguage::ID() const
+{
+       return fICULocale->getName();
+}
+
+
 bool
-BLanguage::IsCountry()
+BLanguage::IsCountrySpecific() const
 {
-       return *(fICULocale->getCountry()) != '\0';
+       return Country() != NULL;
 }
+
+
+bool
+BLanguage::IsVariant() const
+{
+       return Variant() != NULL;
+}

Modified: haiku/trunk/src/kits/locale/LocaleRoster.cpp
===================================================================
--- haiku/trunk/src/kits/locale/LocaleRoster.cpp        2010-05-07 17:30:31 UTC 
(rev 36726)
+++ haiku/trunk/src/kits/locale/LocaleRoster.cpp        2010-05-07 17:38:40 UTC 
(rev 36727)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003-2004, Haiku. All rights reserved.
+ * Copyright 2003-2010, Haiku. All rights reserved.
  * Distributed under the terms of the MIT License.
  *
  * Authors:
@@ -37,8 +37,35 @@
 #include <unicode/locid.h>
 
 
+/*
+ * several attributes/resource-IDs used within the Locale Kit:
+ */
 static const char *kPriorityAttr = "ADDON:priority";
 
+const char *BLocaleRoster::kCatLangAttr = "BEOS:LOCALE_LANGUAGE";
+       // name of catalog language, lives in every catalog file
+const char *BLocaleRoster::kCatSigAttr = "BEOS:LOCALE_SIGNATURE";
+       // catalog signature, lives in every catalog file
+const char *BLocaleRoster::kCatFingerprintAttr = "BEOS:LOCALE_FINGERPRINT";
+       // catalog fingerprint, may live in catalog file
+
+const char *BLocaleRoster::kCatManagerMimeType
+       = "application/x-vnd.Be.locale.catalog-manager";
+       // signature of catalog managing app
+const char *BLocaleRoster::kCatEditorMimeType
+       = "application/x-vnd.Be.locale.catalog-editor";
+       // signature of catalog editor app
+
+const char *BLocaleRoster::kEmbeddedCatAttr = "BEOS:LOCALE_EMBEDDED_CATALOG";
+       // attribute which contains flattened data of embedded catalog
+       // this may live in an app- or add-on-file
+int32 BLocaleRoster::kEmbeddedCatResId = 0xCADA;
+       // a unique value used to identify the resource (=> embedded CAtalog 
DAta)
+       // which contains flattened data of embedded catalog.
+       // this may live in an app- or add-on-file
+
+
+
 typedef BCatalogAddOn *(*InstantiateCatalogFunc)(const char *name,
        const char *language, uint32 fingerprint);
 
@@ -47,7 +74,7 @@
 
 typedef BCatalogAddOn *(*InstantiateEmbeddedCatalogFunc)(
        entry_ref *appOrAddOnRef);
-       
+
 typedef status_t (*GetAvailableLanguagesFunc)(BMessage*, const char*,
        const char*, int32);
 
@@ -211,7 +238,7 @@
                                Locale::setDefault(icuLocale,icuError);
                                assert(icuError == U_ZERO_ERROR);
                                fPreferredLanguages.RemoveName("language");
-                               for (int i = 0; 
settingsMessage.FindString("language", i, 
+                               for (int i = 0; 
settingsMessage.FindString("language", i,
                                                &langName) == B_OK; i++) {
                                        
fPreferredLanguages.AddString("language", langName);
                                }
@@ -310,7 +337,7 @@
                                        priority = -1;
                                        if (node.ReadAttr(kPriorityAttr, 
B_INT8_TYPE, 0,
                                                &priority, sizeof(int8)) <= 0) {
-                                               // add-on has no 
priority-attribute yet, so we load it 
+                                               // add-on has no 
priority-attribute yet, so we load it
                                                // to fetch the priority from 
the corresponding
                                                // symbol...
                                                BString 
fullAddOnPath(addOnFolderName);
@@ -385,34 +412,9 @@
 }
 
 
-/*
- * several attributes/resource-IDs used within the Locale Kit:
- */
-const char *BLocaleRoster::kCatLangAttr = "BEOS:LOCALE_LANGUAGE";
-       // name of catalog language, lives in every catalog file
-const char *BLocaleRoster::kCatSigAttr = "BEOS:LOCALE_SIGNATURE";
-       // catalog signature, lives in every catalog file
-const char *BLocaleRoster::kCatFingerprintAttr = "BEOS:LOCALE_FINGERPRINT";
-       // catalog fingerprint, may live in catalog file
+// #pragma mark - BLocaleRoster
 
-const char *BLocaleRoster::kCatManagerMimeType
-       = "application/x-vnd.Be.locale.catalog-manager";
-       // signature of catalog managing app
-const char *BLocaleRoster::kCatEditorMimeType
-       = "application/x-vnd.Be.locale.catalog-editor";
-       // signature of catalog editor app
 
-const char *BLocaleRoster::kEmbeddedCatAttr = "BEOS:LOCALE_EMBEDDED_CATALOG";
-       // attribute which contains flattened data of embedded catalog
-       // this may live in an app- or add-on-file
-int32 BLocaleRoster::kEmbeddedCatResId = 0xCADA;
-       // a unique value used to identify the resource (=> embedded CAtalog 
DAta)
-       // which contains flattened data of embedded catalog.
-       // this may live in an app- or add-on-file
-
-/*
- * BLocaleRoster, the exported interface to the locale roster data:
- */
 BLocaleRoster::BLocaleRoster()
 {
 }
@@ -473,17 +475,23 @@
 
 
 status_t
-BLocaleRoster::GetLanguage(BLanguage **language, BString languageCode) const
+BLocaleRoster::GetLanguage(const char* languageCode,
+       BLanguage** _language) const
 {
-       if (!language)
+       if (_language == NULL || languageCode == NULL || languageCode[0] == 
'\0')
                return B_BAD_VALUE;
-       *language = new(std::nothrow) BLanguage(languageCode);
+
+       BLanguage* language = new(std::nothrow) BLanguage(languageCode);
+       if (language == NULL)
+               return B_NO_MEMORY;
+
+       *_language = language;
        return B_OK;
 }
 
 
 void
-BLocaleRoster::SetDefaultCountry(BCountry * newDefault) const
+BLocaleRoster::SetDefaultCountry(BCountry* newDefault) const
 {
        gRosterData.fCountryCodeName = newDefault->Code();
        newDefault->DateFormat(gRosterData.fCountryDateFormat, true);
@@ -491,7 +499,7 @@
 
 
 status_t
-BLocaleRoster::GetPreferredLanguages(BMessage *languages) const
+BLocaleRoster::GetPreferredLanguages(BMessage* languages) const
 {
        if (!languages)
                return B_BAD_VALUE;
@@ -548,7 +556,7 @@
 {
        if (languageList == NULL)
                return B_BAD_VALUE;
-       
+
        int32 count = gRosterData.fCatalogAddOnInfos.CountItems();
        for (int32 i = 0; i < count; ++i) {
                BCatalogAddOnInfo *info
@@ -556,11 +564,11 @@
 
                if (!info->MakeSureItsLoaded() || !info->fLanguagesFunc)
                        continue;
-                       
+
                info->fLanguagesFunc(languageList, sigPattern, langPattern,
                        fingerprint);
        }
-       
+
        return B_OK;
 }
 

Modified: haiku/trunk/src/preferences/locale/Jamfile
===================================================================
--- haiku/trunk/src/preferences/locale/Jamfile  2010-05-07 17:30:31 UTC (rev 
36726)
+++ haiku/trunk/src/preferences/locale/Jamfile  2010-05-07 17:38:40 UTC (rev 
36727)
@@ -9,16 +9,15 @@
        Locale.cpp
        LocaleWindow.cpp
        TimeFormatSettingsView.cpp
+
        : be liblocale.so $(TARGET_LIBSTDC++) $(TARGET_LIBSUPC++) 
libicu-common.so
                libicu-data.so libshared.a
        : Locale.rdef
-       ;
+;
 
-DoCatalogs Locale              # application name
-       : x-vnd.Haiku-Locale # app MIME signature
-       :                                       # sources to extract the keys 
from
+DoCatalogs Locale : x-vnd.Haiku-Locale :
+       LanguageListView.cpp
        Locale.cpp
        LocaleWindow.cpp
        TimeFormatSettingsView.cpp
 ;
-

Modified: haiku/trunk/src/preferences/locale/LanguageListView.cpp
===================================================================
--- haiku/trunk/src/preferences/locale/LanguageListView.cpp     2010-05-07 
17:30:31 UTC (rev 36726)
+++ haiku/trunk/src/preferences/locale/LanguageListView.cpp     2010-05-07 
17:38:40 UTC (rev 36727)
@@ -5,6 +5,7 @@
  * Authors:
  *             Stephan Aßmus <superstippi@xxxxxx>
  *             Adrien Destugues <pulkomandy@xxxxxxxxx>
+ *             Axel Dörfler, axeld@xxxxxxxxxxxxxxxx
  *             Oliver Tappe <zooey@xxxxxxxxxxxxxxx>
  */
 
@@ -17,31 +18,46 @@
 
 #include <Bitmap.h>
 #include <Country.h>
+#include <Catalog.h>
+#include <Window.h>
 
-#include "Locale.h"
 
-
 #define MAX_DRAG_HEIGHT                200.0
 #define ALPHA                          170
-#define TEXT_OFFSET                    5.0
 
+#define TR_CONTEXT "LanguageListView"
 
-LanguageListItem::LanguageListItem(const char* text, const char* code)
+
+LanguageListItem::LanguageListItem(const char* text, const char* id,
+       const char* code)
        :
        BStringItem(text),
-       fLanguageCode(code)
+       fID(id),
+       fCode(code)
 {
        // TODO: should probably keep the BCountry as a member of the class
-       BCountry myCountry(code);
-       BRect bounds(0, 0, 15, 15);
-       fIcon = new(std::nothrow) BBitmap(bounds, B_RGBA32);
-       if (fIcon && myCountry.GetIcon(fIcon) != B_OK) {
+       BCountry country(id);
+
+       fIcon = new(std::nothrow) BBitmap(BRect(0, 0, 15, 15), B_RGBA32);
+       if (fIcon != NULL && country.GetIcon(fIcon) != B_OK) {
                delete fIcon;
                fIcon = NULL;
        }
 }
 
 
+LanguageListItem::LanguageListItem(const LanguageListItem& other)
+       :
+       BStringItem(other.Text()),
+       fID(other.ID()),
+       fCode(other.Code()),
+       fIcon(NULL)
+{
+       if (other.fIcon != NULL)
+               fIcon = new BBitmap(*other.fIcon);
+}
+
+
 LanguageListItem::~LanguageListItem()
 {
        delete fIcon;
@@ -51,11 +67,9 @@
 void
 LanguageListItem::DrawItem(BView* owner, BRect frame, bool complete)
 {
-       rgb_color kHighlight = { 140,140,140,0 };
-       rgb_color kBlack = { 0,0,0,0 };
+       rgb_color kHighlight = {140, 140, 140, 0};
+       rgb_color kBlack = {0, 0, 0, 0};
 
-       BRect r(frame);
-
        if (IsSelected() || complete) {
                rgb_color color;
                if (IsSelected())
@@ -64,33 +78,43 @@
                        color = owner->ViewColor();
                owner->SetHighColor(color);
                owner->SetLowColor(color);
-               owner->FillRect(r);
+               owner->FillRect(frame);
                owner->SetHighColor(kBlack);
        } else
                owner->SetLowColor(owner->ViewColor());
 
        frame.left += 4;
        BRect iconFrame(frame);
-       iconFrame.Set(iconFrame.left, iconFrame.top+1, iconFrame.left+15,
-               iconFrame.top+16);
+       iconFrame.Set(iconFrame.left, iconFrame.top + 1, iconFrame.left + 15,
+               iconFrame.top + 16);
 
-       if (fIcon && fIcon->IsValid()) {
+       if (fIcon != NULL && fIcon->IsValid()) {
                owner->SetDrawingMode(B_OP_OVER);
                owner->DrawBitmap(fIcon, iconFrame);
                owner->SetDrawingMode(B_OP_COPY);
        }
 
        frame.left += 16 * (OutlineLevel() + 1);
-       owner->SetHighColor(kBlack);
 
+       BString text = Text();
+       if (IsEnabled())
+               owner->SetHighColor(kBlack);
+       else {
+               owner->SetHighColor(tint_color(owner->LowColor(), 
B_DARKEN_3_TINT));
+               text += " (";
+               text += B_TRANSLATE("already chosen");
+               text += ")";
+       }
+
        BFont font = be_plain_font;
        font_height     finfo;
        font.GetHeight(&finfo);
        owner->SetFont(&font);
-       owner->MovePenTo(frame.left+8, frame.top + ((frame.Height() - 
(finfo.ascent
-                                       + finfo.descent + finfo.leading)) / 2) 
+ (finfo.ascent
-                       + finfo.descent) - 1);
-       owner->DrawString(Text());
+       // TODO: the position is unnecessarily complicated, and not correct 
either
+       owner->MovePenTo(frame.left + 8, frame.top
+               + (frame.Height() - (finfo.ascent + finfo.descent + 
finfo.leading)) / 2
+               + (finfo.ascent + finfo.descent) - 1);
+       owner->DrawString(text.String());
 }
 
 
@@ -100,321 +124,212 @@
 LanguageListView::LanguageListView(const char* name, list_view_type type)
        :
        BOutlineListView(name, type),
-       fMsgPrefLanguagesChanged(new BMessage(kMsgPrefLanguagesChanged))
+       fDeleteMessage(NULL),
+       fDragMessage(NULL)
 {
 }
 
 
 LanguageListView::~LanguageListView()
 {
-       delete fMsgPrefLanguagesChanged;
 }
 
 
-void
-LanguageListView::AttachedToWindow()
+LanguageListItem*
+LanguageListView::ItemForLanguageID(const char* id, int32* _index) const
 {
-       BOutlineListView::AttachedToWindow();
-       ScrollToSelection();
+       for (int32 index = 0; index < FullListCountItems(); index++) {
+               LanguageListItem* item
+                       = static_cast<LanguageListItem*>(FullListItemAt(index));
+
+               if (item->ID() == id) {
+                       if (_index != NULL)
+                               *_index = index;
+                       return item;
+               }
+       }
+
+       return NULL;
 }
 
 
-void
-LanguageListView::MoveItems(BList& items, int32 index)
+LanguageListItem*
+LanguageListView::ItemForLanguageCode(const char* code, int32* _index) const
 {
-       // TODO : only allow moving top level item around other top level
-       // or sublevels within the same top level
+       for (int32 index = 0; index < FullListCountItems(); index++) {
+               LanguageListItem* item
+                       = static_cast<LanguageListItem*>(FullListItemAt(index));
 
-       DeselectAll();
-
-       // collect all items that must be moved (adding subitems as necessary)
-       int32 count = items.CountItems();
-       BList itemsToBeMoved;
-       for (int32 i = 0; i < count; i++) {
-               BListItem* item = (BListItem*)items.ItemAt(i);
-               itemsToBeMoved.AddItem(item);
-               if (item->OutlineLevel() == 0) {
-                       // add all subitems, as they need to be moved, too
-                       int32 subItemCount = CountItemsUnder(item, true);
-                       for (int subIndex = 0; subIndex < subItemCount ; 
subIndex++)
-                               itemsToBeMoved.AddItem(ItemUnderAt(item, true, 
subIndex));
+               if (item->Code() == code) {
+                       if (_index != NULL)
+                               *_index = index;
+                       return item;
                }
        }
 
-       // now remove all the items backwards (in order to remove children 
before
-       // their parent), decreasing target index if we are removing items 
before
-       // it
-       count = itemsToBeMoved.CountItems();
-       for (int32 i = count - 1; i >= 0; i--) {
-               BListItem* item = (BListItem*)itemsToBeMoved.ItemAt(i);
-               int32 removeIndex = FullListIndexOf(item);
-               if (RemoveItem(item)) {
-                       if (removeIndex < index)
-                               index--;
-               }
-       }
-
-       // finally add all the items at the given index
-       for (int32 i = 0; i < count; i++) {
-               BListItem* item = (BListItem*)itemsToBeMoved.ItemAt(i);
-               if (AddItem(item, index))
-                       index++;
-               else
-                       delete item;
-       }
+       return NULL;
 }
 
 
 void
-LanguageListView::MessageReceived(BMessage* message)
+LanguageListView::SetDeleteMessage(BMessage* message)
 {
-       if (message->what == 'DRAG') {
-               // Someone just dropped something on us
-               LanguageListView* list = NULL;
-               if (message->FindPointer("list", (void**)&list) == B_OK) {
-                       // It comes from a list
-                       int32 count = CountItems();
-                       if (fDropIndex < 0 || fDropIndex > count)
-                               fDropIndex = count;
+       delete fDeleteMessage;
+       fDeleteMessage = message;
+}
 
-                       if (list == this) {
-                               // It comes from ourselves : move the item 
around in the list
-                               BList items;
-                               int32 index;
-                               for (int32 i = 0;
-                                       message->FindInt32("index", i, &index) 
== B_OK; i++) {
-                                       if (BListItem* item = 
FullListItemAt(index))
-                                               items.AddItem((void*)item);
-                               }
 
-                               if (items.CountItems() > 0) {
-                                       // There is something to move
-                                       LanguageListItem* parent = 
static_cast<LanguageListItem*>(
-                                               
Superitem(static_cast<LanguageListItem*>(
-                                                               
items.FirstItem())));
-                                       if (parent) {
-                                               // item has a parent - it 
should then stay
-                                               // below it
-                                               if 
(Superitem(FullListItemAt(fDropIndex - 1)) == parent
-                                                       || 
FullListItemAt(fDropIndex - 1) == parent)
-                                                       MoveItems(items, 
fDropIndex);
-                                       } else {
-                                               // item is top level and should 
stay so.
-                                               if 
(Superitem(FullListItemAt(fDropIndex - 1)) == NULL)
-                                                       MoveItems(items, 
fDropIndex);
-                                               else {
-                                                       int itemCount = 
CountItemsUnder(
-                                                               
FullListItemAt(fDropIndex), true);
-                                                       MoveItems(items, 
FullListIndexOf(Superitem(
-                                                                               
FullListItemAt(fDropIndex - 1))
-                                                                       + 
itemCount));
-                                               }
-                                       }
-                               }
-                               fDropIndex = -1;
-                       } else {
-                               // It comes from another list : move it here
+void
+LanguageListView::SetDragMessage(BMessage* message)
+{
+       delete fDragMessage;
+       fDragMessage = message;
+}
 
-                               // ensure we always drop things at top-level 
and not
-                               // in the middle of another outline
-                               if (Superitem(FullListItemAt(fDropIndex))) {
-                                       // Item has a parent
-                                       fDropIndex = 
FullListIndexOf(Superitem(FullListItemAt(
-                                                               fDropIndex)));
-                               }
 
-                               // Item is now a top level one - we must insert 
just below its
-                               // last child
-                               fDropIndex += 
CountItemsUnder(FullListItemAt(fDropIndex), true)
-                                       + 1;
-
-                               int32 indexCount;
-                               type_code dummy;
-                               if (message->GetInfo("index", &dummy, 
&indexCount) == B_OK) {
-                                       for (int32 i = indexCount - 1; i >= 0; 
i--) {
-                                               int32 index;
-                                               if (message->FindInt32("index", 
i, &index) == B_OK)
-                                                       MoveItemFrom(list, 
index, fDropIndex);
-                                       }
-                               }
-
-                               fDropIndex = -1;
-                       }
-                       Invoke(fMsgPrefLanguagesChanged);
-               }
-       } else
-               BOutlineListView::MessageReceived(message);
+void
+LanguageListView::AttachedToWindow()
+{
+       BOutlineListView::AttachedToWindow();
+       ScrollToSelection();
 }
 
 
 void
-LanguageListView::MoveItemFrom(BOutlineListView* origin, int32 index,
-       int32 dropSpot)
+LanguageListView::MessageReceived(BMessage* message)
 {
-       // Check that the node we are going to move is a top-level one.
-       // If not, we want its parent instead
-       LanguageListItem* itemToMove = static_cast<LanguageListItem*>(
-               origin->Superitem(origin->FullListItemAt(index)));
-       if (itemToMove == NULL) {
-               itemToMove = static_cast<LanguageListItem*>(
-                       origin->FullListItemAt(index));
-               if (itemToMove == NULL)
-                       return;
-       } else
-               index = origin->FullListIndexOf(itemToMove);
+       if (message->WasDropped() && _AcceptsDragMessage(message)) {
+               // Someone just dropped something on us
+               BMessage dragMessage(*message);
+               dragMessage.AddInt32("drop_index", fDropIndex);
+               dragMessage.AddPointer("drop_target", this);
 
-       // collect all items that must be moved (adding subitems as necessary)
-       BList itemsToBeMoved;
-       itemsToBeMoved.AddItem(itemToMove);
-       // add all subitems, as they need to be moved, too
-       int32 subItemCount = origin->CountItemsUnder(itemToMove, true);
-       for (int32 subIndex = 0; subIndex < subItemCount; subIndex++) {
-               itemsToBeMoved.AddItem(origin->ItemUnderAt(itemToMove, true,
-                       subIndex));
-       }
-
-       // now remove all items from origin in reverse order (to remove the 
children
-       // before the parent) ...
-       // TODO: using RemoveItem() on the parent will delete the subitems, 
which
-       //       may be a bug, actually.
-       int32 itemCount = itemsToBeMoved.CountItems();
-       for (int32 i = itemCount - 1; i >= 0; i--)
-               origin->RemoveItem(index + i);
-       // ... and add all the items to this list
-       AddList(&itemsToBeMoved, dropSpot);
+               Invoke(&dragMessage);
+       } else
+               BOutlineListView::MessageReceived(message);
 }
 
 
 bool
-LanguageListView::InitiateDrag(BPoint point, int32 index, bool)
+LanguageListView::InitiateDrag(BPoint point, int32 dragIndex,
+       bool /*wasSelected*/)
 {
-       bool success = false;
+       if (fDragMessage == NULL)
+               return false;
+
        BListItem* item = FullListItemAt(CurrentSelection(0));
-       if (!item) {
+       if (item == NULL) {
                // workaround for a timing problem
-               Select(index);
-               item = FullListItemAt(index);
+               // TODO: this should support extending the selection
+               item = ItemAt(dragIndex);
+               Select(dragIndex);
        }
-       if (item) {
-               // create drag message
-               BMessage msg('DRAG');
-               msg.AddPointer("list", (void*)(this));
-               // first selection round, consider only superitems
-               int32 index;
-               for (int32 i = 0; (index = FullListCurrentSelection(i)) >= 0; 
i++) {
-                       BListItem* item = FullListItemAt(index);
-                       if (item == NULL)
-                               return false;
-                       if (item->OutlineLevel() == 0)
-                               msg.AddInt32("index", index);
+       if (item == NULL)
+               return false;
+
+       // create drag message
+       BMessage message = *fDragMessage;
+       message.AddPointer("listview", this);
+
+       for (int32 i = 0;; i++) {
+               int32 index = FullListCurrentSelection(i);
+               if (index < 0)
+                       break;
+
+               message.AddInt32("index", index);
+       }
+
+       // figure out drag rect
+
+       BRect dragRect(0.0, 0.0, Bounds().Width(), -1.0);
+       int32 numItems = 0;
+       bool fade = false;
+
+       // figure out, how many items fit into our bitmap
+       for (int32 i = 0, index; message.FindInt32("index", i, &index) == B_OK;
+                       i++) {
+               BListItem* item = FullListItemAt(index);
+               if (item == NULL)
+                       break;
+
+               dragRect.bottom += ceilf(item->Height()) + 1.0;
+               numItems++;
+
+               if (dragRect.Height() > MAX_DRAG_HEIGHT) {
+                       dragRect.bottom = MAX_DRAG_HEIGHT;
+                       fade = true;
+                       break;
                }
-               if (!msg.HasInt32("index")) {
-                       // second selection round, consider only subitems of 
the same
-                       // (i.e. the first) parent
-                       BListItem* seenSuperItem = NULL;
-                       for (int32 i = 0; (index = FullListCurrentSelection(i)) 
>= 0; i++) {
-                               BListItem* item = FullListItemAt(index);
-                               if (item == NULL)
-                                       return false;
-                               if (item->OutlineLevel() != 0) {
-                                       BListItem* superItem = Superitem(item);
-                                       if (seenSuperItem == NULL)
-                                               seenSuperItem = superItem;
-                                       if (superItem == seenSuperItem)
-                                               msg.AddInt32("index", index);
-                                       else
-                                               break;
-                               }
-                       }
-               }
+       }
 
-               // figure out drag rect
-               float width = Bounds().Width();
-               BRect dragRect(0.0, 0.0, width, -1.0);
-               // figure out, how many items fit into our bitmap
-               bool fade = false;
-               int32 numItems;
-               int32 currIndex;
-               BListItem* item;
-               for (numItems = 0;
-                       msg.FindInt32("index", numItems, &currIndex) == B_OK
-                               && (item = FullListItemAt(currIndex)) != NULL; 
numItems++) {
-                       dragRect.bottom += ceilf(item->Height()) + 1.0;
-                       if (dragRect.Height() > MAX_DRAG_HEIGHT) {
-                               fade = true;
-                               dragRect.bottom = MAX_DRAG_HEIGHT;
-                               numItems++;
-                               break;
-                       }
+       BBitmap* dragBitmap = new BBitmap(dragRect, B_RGB32, true);
+       if (dragBitmap->IsValid()) {
+               BView* view = new BView(dragBitmap->Bounds(), "helper", 
B_FOLLOW_NONE,
+                       B_WILL_DRAW);
+               dragBitmap->AddChild(view);
+               dragBitmap->Lock();
+               BRect itemBounds(dragRect) ;
+               itemBounds.bottom = 0.0;
+               // let all selected items, that fit into our drag_bitmap, draw
+               for (int32 i = 0; i < numItems; i++) {
+                       int32 index = message.FindInt32("index", i);
+                       LanguageListItem* item
+                               = 
static_cast<LanguageListItem*>(FullListItemAt(index));
+                       itemBounds.bottom = itemBounds.top + 
ceilf(item->Height());
+                       if (itemBounds.bottom > dragRect.bottom)
+                               itemBounds.bottom = dragRect.bottom;
+                       item->DrawItem(view, itemBounds);
+                       itemBounds.top = itemBounds.bottom + 1.0;
                }
-               BBitmap* dragBitmap = new BBitmap(dragRect, B_RGB32, true);
-               if (dragBitmap && dragBitmap->IsValid()) {
-                       BView* v = new BView(dragBitmap->Bounds(), "helper", 
B_FOLLOW_NONE,
-                               B_WILL_DRAW);
-                       dragBitmap->AddChild(v);
-                       dragBitmap->Lock();
-                       BRect itemBounds(dragRect) ;
-                       itemBounds.bottom = 0.0;
-                       // let all selected items, that fit into our 
drag_bitmap, draw
-                       for (int32 i = 0; i < numItems; i++) {
-                               int32 index = msg.FindInt32("index", i);
-                               LanguageListItem* item
-                                       = 
static_cast<LanguageListItem*>(FullListItemAt(index));
-                               itemBounds.bottom = itemBounds.top + 
ceilf(item->Height());
-                               if (itemBounds.bottom > dragRect.bottom)
-                                       itemBounds.bottom = dragRect.bottom;
-                               item->DrawItem(v, itemBounds);
-                               itemBounds.top = itemBounds.bottom + 1.0;
-                       }
-                       // make a black frame arround the edge
-                       v->SetHighColor(0, 0, 0, 255);
-                       v->StrokeRect(v->Bounds());
-                       v->Sync();
+               // make a black frame arround the edge
+               view->SetHighColor(0, 0, 0, 255);
+               view->StrokeRect(view->Bounds());
+               view->Sync();
 
-                       uint8* bits = (uint8*)dragBitmap->Bits();
-                       int32 height = (int32)dragBitmap->Bounds().Height() + 1;
-                       int32 width = (int32)dragBitmap->Bounds().Width() + 1;
-                       int32 bpr = dragBitmap->BytesPerRow();
+               uint8* bits = (uint8*)dragBitmap->Bits();
+               int32 height = (int32)dragBitmap->Bounds().Height() + 1;
+               int32 width = (int32)dragBitmap->Bounds().Width() + 1;
+               int32 bpr = dragBitmap->BytesPerRow();
 
-                       if (fade) {
-                               for (int32 y = 0; y < height - ALPHA / 2; y++, 
bits += bpr) {
-                                       uint8* line = bits + 3;
-                                       for (uint8* end = line + 4 * width; 
line < end; line += 4)
-                                               *line = ALPHA;
-                               }
-                               for (int32 y = height - ALPHA / 2; y < height;
-                                       y++, bits += bpr) {
-                                       uint8* line = bits + 3;
-                                       for (uint8* end = line + 4 * width; 
line < end; line += 4)
-                                               *line = (height - y) << 1;
-                               }
-                       } else {
-                               for (int32 y = 0; y < height; y++, bits += bpr) 
{
-                                       uint8* line = bits + 3;
-                                       for (uint8* end = line + 4 * width; 
line < end; line += 4)
-                                               *line = ALPHA;
-                               }
+               if (fade) {

[... truncated: 805 lines follow ...]

Other related posts:

  • » [haiku-commits] r36727 - in haiku/trunk: headers/os/locale src/kits/locale src/preferences/locale - axeld