Generated reference › API — ICoreBlocks/ICoreStudio/StudioObjects/Panels/ICoreAccount
kind: generated#api#icoreblocks-icorestudio-studioobjects-panels-icoreaccount

API — ICoreBlocks/ICoreStudio/StudioObjects/Panels/ICoreAccount

The public contract of 4 header(s) under src/ICoreBlocks/ICoreStudio/StudioObjects/Panels/ICoreAccount — 4 class/struct definition(s), 52 declaration(s). Each section shows the header's banner and its public (and protected-virtual) surface exactly as the file writes it.

HeaderDefinesDeclarationsBases
ICoreAccountPanel.hICoreAccountPanel12public ICoreWidget
ICoreLicenseBanner.hICoreLicenseBanner13public ICoreWidget
ICoreLicenseStateLabel.hICoreLicenseStateLabel6public ICoreWidget
ICoreSignInDialog.hICoreSignInDialog21public ICoreDialog

ICoreAccountPanel.h#

src/ICoreBlocks/ICoreStudio/StudioObjects/Panels/ICoreAccount/ICoreAccountPanel.h

ICoreAccountPanel#

ICoreAccountPanel.h:42 · class · final · bases public ICoreWidget · pImpl · 12 declaration(s)

ICoreAccountPanel — who is signed in, what this copy is allowed to do, and what THIS MACHINE is holding.

class ICoreAccountPanel final : public ICoreWidget {
public:
    explicit ICoreAccountPanel(ICoreWidget* parent = nullptr);
    ~ICoreAccountPanel() override;

    // The gate this panel reads and deactivates through. NOT OWNED. Display
    // facts come from icore::License, which needs nothing bound; the two
    // ACTIONS (refresh, deactivate this machine) need the gate itself.
    void setGate(ICoreLicenseGate* gate);

    // Re-reads everything. Call it when the licence state moves; the panel does
    // not subscribe to icore::License, because that view carries one callback
    // and a widget taking it would unhook the shell's.
    void refresh();

    // ---- what it currently says, so a suite can assert sentences ----------

    [[nodiscard]] ICoreString identityText() const;
    [[nodiscard]] ICoreString licenceText() const;
    [[nodiscard]] ICoreString machineText() const;
    [[nodiscard]] ICoreString vaultDisclosureText() const;

    // The provisioning sentence, or EMPTY when this session resolved a licence
    // the ordinary way. Non-empty means ICoreLicenseGate::resolvedFromEnvironment()
    // — the MACHINE is licensed, by a signed ICORE_LICENSE_TOKEN in the
    // environment, and nobody signed in.
    //
    // ⚠ THE PANEL SAID NOTHING ABOUT THIS UNTIL A3.4, and it is what made a
    // sign-out look broken: the panel showed a licence for an account nobody
    // had signed into, sign-out emptied it, and the next launch put it back.
    // The gate had answered the question all along and no caller in src/ asked.
    [[nodiscard]] ICoreString provisioningText() const;

    // What the session button currently offers — "Sign out" while signed in,
    // "Sign in" when not. Exposed for the same reason the sentences above are:
    // so a suite can assert the flip instead of a human noticing it.
    [[nodiscard]] ICoreString sessionActionText() const;

    // The portal, spelled once. The panel's link and any "manage seats" text
    // both read this.
    //
    // ⚠ IT IS ITS OWN HOST — `portal.systemsicore.com`, a separate Cloudflare
    // Worker — and NOT a path on the marketing site. `systemsicore.com/account`
    // is not a route and never was; this link pointed at it until 2026-08-24.
    [[nodiscard]] static ICoreString portalUrl();

    // The same one place with the scheme trimmed, for PROSE that names where to
    // go ("release a machine from your account on …"). A sentence spelling the
    // host itself would be a second copy of this fact, and the second copy is
    // the one that does not get changed.
    [[nodiscard]] static ICoreString portalHost();

    // Sign-out completed. ⚠ THE HOST MUST PUT THE WALL BACK UP — this session
    // is now Unlicensed, and until 2026-08-24 nothing did: the panel reported a
    // released seat and the editor carried on fully functional until the next
    // launch, with no way to sign in as anybody else. ICorePrimaryWindow raises
    // the sign-in dialog from here.
    //
    // Was `onDeactivated` while the button said "Deactivate this machine".
    ICoreSignal<> onSignedOut;

    // The session button was pressed while signed OUT. ⚠ The host raises the
    // LOCAL sign-in dialog — not the portal. Signing in is something this
    // application does over the gate it already holds; the portal is where the
    // things this panel deliberately does not show live (seats, invoices, org
    // admin), and sending a user there to get back into the app they are
    // already looking at would be a detour with a browser in it.
    //
    // It goes through the host for the same reason onSignedOut does: the wall
    // belongs to the window, which knows to refresh the banner afterwards, and
    // two places constructing it is two places to keep in step.
    ICoreSignal<> onSignInRequested;

private:
    class Impl;                    // the two-line residue; state lives here
    std::unique_ptr<Impl> impl;
};

ICoreLicenseBanner.h#

src/ICoreBlocks/ICoreStudio/StudioObjects/Panels/ICoreAccount/ICoreLicenseBanner.h

ICoreLicenseBanner#

ICoreLicenseBanner.h:42 · class · final · bases public ICoreWidget · pImpl · 13 declaration(s)

ICoreLicenseBanner — the one thing the licence is allowed to put in front of a user who is working.

class ICoreLicenseBanner final : public ICoreWidget {
public:
    explicit ICoreLicenseBanner(ICoreWidget* parent = nullptr);
    ~ICoreLicenseBanner() override;

    // The height the host should reserve when the banner is visible. It is
    // ICoreBannerStrip::HEIGHT, spelled through that constant rather than
    // repeated, so the two banners cannot end up different heights.
    static const int BANNER_HEIGHT;

    // Reads icore::License::instance() and re-decides. Cheap; call it from
    // wherever the shell learns the state changed.
    void refreshFromLicense();

    // The same decision with the values handed in — what a test drives, and
    // what a host with its own state already in hand should call.
    void setState(icore::LicenseState state, int graceDaysRemaining);

    // Whether this state is one of the two that show anything. A host can ask
    // before it makes room, and a test can assert it without a screen.
    [[nodiscard]] static bool isBannerState(icore::LicenseState state);

    // What the strip currently says, so a suite can assert the sentence rather
    // than a screenshot. Empty when the banner is not showing.
    [[nodiscard]] ICoreString message() const;

    // Grace only, and only until the next state change.
    void dismissForThisSession();
    [[nodiscard]] bool isDismissed() const;

    // "Account…" was pressed. The host opens ICoreAccountPanel; the banner
    // deliberately does not know how to.
    ICoreSignal<> onAccountRequested;

    // The strip showed or hid itself; the host re-stacks the strips under the
    // top panel (ICoreStudioSurface::relayoutStripsUnderTopPanel), so the
    // update banner below it moves up or down (2026-09-28).
    ICoreSignal<> onVisibilityChanged;

protected:
    void paintContent(ICorePainter& painter) override;

    // ⚠ IT FLOATS OVER THE CANVAS NOW (owner, 2026-09-25: under the top panel,
    // not under the title bar -- ICoreStudioSurface::addStripUnderTopPanel), so
    // a gesture on its bare ground is swallowed, for the reason
    // ICoreTopFixedPanel gives: a declined press or wheel walks on and pans,
    // zooms or deselects the diagram underneath. Its buttons are children and
    // are offered the gesture first, so they answer as before.
    bool mousePressed(const ICoreMouseEvent& event) override;
    bool mouseReleased(const ICoreMouseEvent& event) override;
    bool mouseDoubleClicked(const ICoreMouseEvent& event) override;
    bool wheelScrolled(const ICoreWheelEvent& event) override;

private:
    class Impl;                    // the two-line residue; state lives here
    std::unique_ptr<Impl> impl;
};

ICoreLicenseStateLabel.h#

src/ICoreBlocks/ICoreStudio/StudioObjects/Panels/ICoreAccount/ICoreLicenseStateLabel.h

ICoreLicenseStateLabel#

ICoreLicenseStateLabel.h:39 · class · final · bases public ICoreWidget · pImpl · 6 declaration(s)

ICoreLicenseStateLabel — the one-word licence badge at the foot of the primary window's left rail (owner, 2026-09-25).

class ICoreLicenseStateLabel final : public ICoreWidget {
public:
    explicit ICoreLicenseStateLabel(ICoreWidget* parent = nullptr);
    ~ICoreLicenseStateLabel() override;

    // The height it takes when showing: the badge plus the gap above it.
    static const int LABEL_HEIGHT;

    // Reads icore::License::instance() and re-decides.
    void refreshFromLicense();

    // The same decision with the values handed in -- what a test drives.
    void setState(icore::LicenseState state, const std::string& tierId);

    // What it currently says; empty when it is not showing.
    [[nodiscard]] ICoreString text() const;

protected:
    void paintContent(ICorePainter& painter) override;

private:
    class Impl;                    // the two-line residue; state lives here
    std::unique_ptr<Impl> impl;
};

ICoreSignInDialog.h#

src/ICoreBlocks/ICoreStudio/StudioObjects/Panels/ICoreAccount/ICoreSignInDialog.h

ICoreSignInDialog#

ICoreSignInDialog.h:47 · class · final · bases public ICoreDialog · pImpl · 21 declaration(s)

ICoreSignInDialog — the wall's face.

class ICoreSignInDialog final : public ICoreDialog {
public:
    explicit ICoreSignInDialog(ICoreWidget* parent = nullptr);
    ~ICoreSignInDialog() override;

    // Which of the two forms is showing. THE EMAIL AND PASSWORD ARE THE
    // DEFAULT (owner, 2026-08-25): it is what somebody who has just bought has
    // to hand, and the account route can reach a licence the person never
    // copied anywhere. The key route stays one click away for the boxed or
    // invoiced customer, and it is still the only one that can be checked
    // before the network is touched.
    //
    // ⚠ A CASE THAT DRIVES THE KEY ROUTE MUST SAY SO. submit() reads this
    // member, not the field that happens to be filled, so a suite that sets a
    // licence key and submits without calling setMethod() now sends an empty
    // credentials form and is refused for the wrong reason.
    enum class Method { LicenseKey, EmailAndPassword };

    void   setMethod(Method method);
    [[nodiscard]] Method method() const;

    // What the method picker READS, as a user sees it.
    //
    // ⚠ IT EXISTS BECAUSE THE DEFAULT HAS TWO HALVES: the member above decides
    // which form is visible, the combo's own selection decides what the control
    // says, and they are set on two different lines. Change one and the window
    // opens showing a form the picker does not name — a mismatch every case
    // driving this dialog through method() would call correct.
    [[nodiscard]] ICoreString methodLabel() const;

    // The gate the dialog activates through. NOT OWNED, and may be null: with
    // no gate the button reports that licensing is not running in this build
    // instead of silently doing nothing.
    void setGate(ICoreLicenseGate* gate);

    // ---- the fields, so a suite can drive this with no screen -------------

    void setLicenseKey(const ICoreString& key);
    void setEmail(const ICoreString& email);
    void setPassword(const ICoreString& password);

    [[nodiscard]] ICoreString licenseKey() const;
    [[nodiscard]] ICoreString email() const;

    // What "Sign in" does. False means nothing was sent — the offline check
    // refused, a field is empty, or there is no gate — and statusText() says
    // which. True means a request is in flight; onSignedIn fires if it lands.
    bool submit();

    // The sentence under the form. Never empty after a failed submit().
    [[nodiscard]] ICoreString statusText() const;

    // WHICH BUTTON RETURN PRESSES. "Sign in", in every step and from any field.
    //
    // ⚠ IT EXISTS BECAUSE NOBODY DECLARED ONE. No button asked to be the
    // default, so the answer was settled at SHOW time, by Qt, from the child
    // order -- and "Create an account" is built first because it must sit left
    // of the stretch, so Enter on a filled-in form opened a browser at the
    // registration page and sent no activation. The footer's layout position and
    // the meaning of the Return key are two different decisions, and nothing in
    // this dialog's API could see the second one until this seam.
    //
    // ⚠ IT READS THE DECLARED DEFAULT, NOT A SIMULATED KEY PRESS -- the GuiLab
    // has no way to send one. Measured 2026-08-26 with the three calls in the
    // footer removed: this answered EMPTY on a dialog that had never been shown,
    // which is the shape of the defect (nothing claimed it) rather than the
    // symptom (Qt handed it to the first button). A case that wanted the symptom
    // would need a shown dialog and a Return event, and would still be asserting
    // Qt's rule rather than this dialog's decision.
    [[nodiscard]] ICoreString defaultButtonText() const;

    // Where the licence picker sits inside the dialog, in pixels from the top,
    // or -1 when it is not showing.
    //
    // ⚠ IT EXISTS BECAUSE IT SHIPPED AT ZERO. The picker was added to the page
    // layout on a line that ran BEFORE the line that constructed it, so the
    // layout was handed a null pointer, the widget was parented to the dialog
    // and never positioned, and it drew itself over the heading at (0,0).
    // `addWidget(nullptr)` says nothing, and every case in the suite drives
    // this dialog through its API rather than its geometry — so nothing in the
    // tree could see it and a person had to notice. This is the seam that
    // makes it visible to a test.
    [[nodiscard]] int licenseChoiceTop() const;

    // Where "Create an account" sends a user who has nothing to type into this
    // dialog yet. Registration, payment and the licence key that comes out of
    // it are the portal's, exactly as seats and invoices are — the dialog links
    // to it rather than growing a second copy of it.
    //
    // ⚠ IT DELEGATES TO ICoreAccountPanel::portalUrl() AND SPELLS NOTHING
    // ITSELF. A "/signup" path here would be a second spelling of the portal
    // AND an invented route: the portal Worker serves its root and answers 404
    // at /signup, /register and /sign-up (probed 2026-08-24), which is the same
    // defect as the `systemsicore.com/account` link this dialog's messages
    // carried until that day — a control that leads nowhere.
    [[nodiscard]] static ICoreString registrationUrl();

    // Opens registrationUrl() in the user's browser and writes the status line
    // saying so. Exposed so a suite can drive the button's whole effect; the
    // browser is the platform's and nothing here waits on it.
    void openRegistrationPage();

    // The seat fingerprint as a HUMAN reads it: the salted hash, truncated, with
    // the ellipsis already on it. Never the raw platform id.
    //
    // ⚠ ONE SPELLING OF THE TRUNCATION, deliberately. Two places show this — the
    // wall's dialog and the account panel — and a fingerprint shown 12 characters
    // long in one and 16 in the other is a support call where neither end can
    // tell whether they are looking at the same machine. The salt already lives
    // in exactly one place for the same reason; this is the display half of it.
    [[nodiscard]] static std::string elidedSeatFingerprint();

    // Everything about THIS MACHINE that an activation carries, filled in.
    // Credentials are the caller's half; this is the half that must never
    // contain the raw machine id.
    [[nodiscard]] static ICoreActivationRequest describeThisMachine();

    // One sentence per error code the Worker and the gate can answer with, and
    // NO TWO ARE THE SAME — collapsing "seat limit reached" into "sign-in
    // failed" is the defect this exists to prevent, and it is invisible in
    // review. An unknown code is not an error to hide: it is reported as
    // itself, because a build that has not learned a code is still able to
    // tell the user what the server said.
    [[nodiscard]] static ICoreString errorText(const std::string& errorCode);

    // Every code errorText() knows, for the case that asserts distinctness.
    [[nodiscard]] static std::vector<std::string> knownErrorCodes();

    // The licence was accepted and stored. The wall's host closes on this.
    ICoreSignal<> onSignedIn;

private:
    class Impl;                    // the two-line residue; state lives here
    std::unique_ptr<Impl> impl;
};