In preparation for implementing Undo/Redo support, we need _Insert() to
take a TextDocument instead of a BString, CharacterStyle and ParagraphStyle.
When a chunk of the TextDocument has been removed, we need to be able to
Insert() that as part of the Undo operation. Not well tested, but typing
still works.
Added TODO about which data the TextChangedEvent should have in order to
know how to respond in the TextDocumentLayout. For now, update all paragraphs
in the layout, add new ones as necessary, and remove the ones we have in
excess by using Invalidate().
Make sure that the caret starts blinking half a second after it last moved.
The previous solution using Pulse() had a number of problems:
* The caret could be hidden during moving it or during typing. It would then
be shown again very soon after, i.e. when typing the next character or
when moving it to the next offset. But it looks bad anyway.
* When the caret stopped moving, it started blinking a random amount of
time afterwards, getting back into the rhythm of Pulse() messages.
However, starting to blink a constant time after the caret last moved,
looks much more satisfying.
... and invalidate based on TextChangedEvents. I am not yet sure whether
TextChangeEvent needs separate counts for removed and changed paragraphs.
It is most likely not yet correct and may either update too many paragraph
layouts or miss updating some at the end.
TextDocument:
* Moved implementation of Remove() and Insert() into private methods.
* Reimplement all public Insert() methods and Remove() on top of Replace().
* In Replace(), send a TextChangedEvent. Added TODO for sending a
TextChangingEvent, although at this point, I am not sure if it will be
needed at all.
Basically synced the code with what I did for WIP WonderBrush rewrite.
* Converted to use layouting
* Removed unused liblayout MView cruft
* Removed need for rendering in separate threads in favor of
rendering lazily. The original Colors! rendering was insanely slow
and inefficient, hence the separate rendering threads.
* Some style fixes along the way.
* Some minor bug fixes, too, but these were not actually triggered.
* Renamed selected_color_mode.h to SelectedColorMode.h
Generate bitmap in Draw() lazily. Removed liblayout stuff. Support for
Haiku layout methods. Fixed some bugs with selecting red/green/blue
as fixed values (ticket #10574).
* The name is the static package name. The title is either that name,
or a translated pretty version of the name.
* Adjust package info retrieval to server API changes. Unbreaks package
translations.
This is all work in progress. The plan is to move the code that does any
actual changes to the TextDocument into UndoableEdit implementations, then
emit these edits to interesed listeners. They can then store them to
implement the edit history. If there are not listeners, the edits will
simply be released after they've done their work.
Implemented so far is only the support for storing the edit listeners.
No, not updating packages via HaikuDepot, but a light-weight synchronization
between the system package manager list and the HaikuDepot model. After
installing or removing a package, HaikuDepot performed a very costly update
of all information by basically throwing everything away and reloading it.
Implements #11786.
... in PackageInfoView::SetPackage() and Clear(). The sub-views reference
stuff from the previous PackageInfo instance. If we release the reference
before adopting the new package, the sub-views may still access stuff from
the previous package. For example the PackageActionView tries to avoid
rebuilding the button list and compares previous package actions to the
new actions. Particularily after the package list has been rebuild, we have
only new PackageInfo instances and the PackageInfoView may hold on to a
PackageInfo that is not still referenced anywhere else. Would be a good
explanation for #11785.
Since the package information is refreshed asynchronously, some packages
may fit the current filter parameters. Check for this situation more
generically in the MSG_PACKAGE_CHANGED notification. Before, it was only
done for prominent packages to make them appear in the Featured packages
view. The problem was visible by for example selecting a category and then
refreshing packages. Many of the previously shown packages would be missing
and magically appear when changing filter parameters slightly and back
to what they were.
When trying to find a matching parent item, we cannot rely on cached
pointers to BPackageEntries, since those are re-used per entry level
from the BPackageReader. Instead, we build the package entry path as
a string and store that with the list item.
Removed debug output.
Most changes were in the PackageContentOutliner and its HandleEntry() method
to make it work correctly. The parent entry of a visited entry may not be
the last parent entry, but some other previously added entry. We need a
PackageEntryItem class to also store the BPackageEntry together with the
list item.
Other small fixes.
Let Model::PopulatePackage() have a mode where it forces the update on a
package that has already been populated. Trigger populating from success
code path in RatePackageWindow. Fixes#11638.
If the visible packages list does not contain the currently showing package
anymore after filter parameters have changed, clear the package info area.
This also means that when installed packages are turned off, which means
a package will disappear from the list after being installed, the package
will no longer keep showing in the info area. This situation is less likely
with the change that installed packages will now show by default and the
user has to explicitly turn them off.
Since the fVisiblePackages list in MainWindow is now also filtered by
featured packages, and since the "featured" status of packages is collected
asynchronously, the list needs to be updated in the package changed
notification. Also, the package should only be added to the featured packages
view if it is now in the visible list. Other filter criteria would not be
taken into account otherwise. Fixes#11663
* Renamed the "Option" menu to "Show", removed the now redundant "Show" from
the items in that menu.
* Add an "Only featured packages" item in the Show menu. This item is disabled
as soon as the user types something in the search terms field. Othetwise,
this setting is respected, i.e. one can combine the featured setting with
other settings, i.e. show all featured packages of a certain depot and in a
certain category.
* Added PackageInfo::IsProminent() and removed the respective method from
the MainWindow (which only considered a package prominent if it was not
yet installed).
* "Show -> Installed packages" now defaults to on. There have been complaints
on Trac and I guess rightfully so. The use-cases in which one starts
HaikuDepot and wants to know about installed packages are just as likely
as the use-case where one wants to install new software.
The packages count view centers its label. It therefore needs a full update
on resize. Also optimize SetItemCount() by trying to avoid unneccessary
layout invalidations.
Clicking the thumbnail in the package info area will now open a
window where the full-size screenshot is downloaded and shown. There can
only be one such screenshot window open. Navigating between multiple
screenshots of a package is not yet implemented. Also, no caching, but
this may be OK as it is, since one usually looks at these only once and
doesn't want the harddrive filling up with screenshots.
Show the summary instead of the version. The layout still sucks, but I will
have to implement some kind of row/flow BLayout to get what I initially had
in mind. Another TODO is to highlight the clicked item somehow.
* Rework existing package listener mechanism to report any interesting
changes. Listen for prominence changes in addition to package state.
* Add featured packages to the FeaturedPackagesView when their prominence
is retrived, and also in _AdoptModel().
* In _AdoptModel(), show the featured packages view when no search filters
are active and installed packages are not shown either. Otherwise show
the list of all packages matching the current filtering.
...into MessagePackageListener and OnePackageMessagePackageListener.
The first one doesn't know which package(s) it's listening to. But it
can filter the change notifications now and only react to certain changes.
The second one knows which package it's listening to.
Not yet visible. But the package list area in the main window has a card
layout now and a second (hidden) page for featured packages. Which packages
are visible there will depend on the prominence value from the web-app
and other parameters later (suggestions based on packages already installed
and user-ratings). At the moment, there is no mechanism for updating the
package list when package info is retrieved asynchronously, even from the
cache. Also, the view should switch to the list when searching and perhaps
in other situations as well, like selecting a category or when no packages
would be featured. And clicking featured packages does not yet select them in
the info area...
Currently a vertically scrollable container for views which are similar
to the title area in the package info view (and share most code, but it
will diverge later on). Untested and not yet used.
Package contents are scanned to find deskbar links. If a package has less
than four links, they will be offered in separate "Open <link name>" buttons
in the package info area. Usually, this results in one button to open the
main application from the package. If the heuristic proves to be not good
enough, this could be improved of course.
Note that double clicking a .hpkg in one of the packages folders will
not yet have a sensible result. I think it should open the regular
HaikuDepot with the full packages list, default to show installed packages
only and pre-select the package that was double clicked. It would be tricky
however if more than one installed package file is opened at once.
The idea is to parse packages for Deskbar links and offer to "open" them
once they are installed. The added functionality is not yet complete and
will eventually figure out the file system location of a package and parse
the contents. I am mainly pushing this since my git-foo is limited and
I want to push the fix for the discovered deadlock.
When the package list was refreshed while package info was still being
pulled from the web app, calling Model::Clear() with the model lock already
held could lead to a dead-lock: The package populator could block on the
model lock to update information, while StopPopulatingAllPackages() waited
for the thread to exit, but held the lock that the thread was blocking on.
So call StopPopulatingAllPackages() before grabbing the lock and calling
Clear() in MainWindow::_RefreshPackageList().
And move the (new) checkmarks into the Options menu. This makes them less
easy to discover, but cleans up the UI, especially since the options to show
development and source code packages are not very important for most users.
There is now a right-aligned second menu bar for the account management.
The menu label is what was previously shown underneath the search terms field.
The menu items have moved from the Tools menu into the new user menu. This
means the login/logout functionality is directly available where the login
info is shown in the UI when you click it.
* Give the PackageManager either the package name, or the path to a local
.hpkg package to Install().
* Implement Warn() to at least print something to the command line. Change
the TODO to show the warning to the user instead.
Consequently always register it with the solver in Init(). This solves the
problem that it made a difference at which time Init() is called. Init() is
called at the beginning of Install() and Uninstall(), but HaikuDepot was
calling it before that for other reasons. A second call to Init() will exit
early. If local package files were added to the PackageManager instance,
the local repository was created lazily, but because Init() did not run a
second time, the local repository was not registered with the solver. Now
it already is, since it is no longer created on demand, but always.