Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implement candidate action: forget candidate #108

Merged
merged 1 commit into from
Jun 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ include(ECMSetupVersion)
include(ECMUninstallTarget)

find_package(Gettext REQUIRED)
find_package(Fcitx5Core 5.1.9 REQUIRED)
find_package(Fcitx5Core 5.1.10 REQUIRED)
find_package(Fcitx5Module REQUIRED COMPONENTS Notifications)
find_package(PkgConfig REQUIRED)

Expand All @@ -19,6 +19,9 @@ if (NOT DEFINED RIME_TARGET)
set(RIME_TARGET PkgConfig::Rime)
endif()

if ("${Rime_VERSION}" VERSION_LESS "1.8.0")
add_definitions(-DFCITX_RIME_NO_DELETE_CANDIDATE)
endif()
if ("${Rime_VERSION}" VERSION_LESS "1.7.0")
add_definitions(-DFCITX_RIME_LOAD_PLUGIN)
endif()
Expand Down
49 changes: 49 additions & 0 deletions src/rimecandidate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ void RimeCandidateWord::select(InputContext *inputContext) const {
}
}

void RimeCandidateWord::forget(RimeState *state) const {
#ifndef FCITX_RIME_NO_DELETE_CANDIDATE
state->deleteCandidate(idx_, /*global=*/false);
#endif
}

#ifndef FCITX_RIME_NO_SELECT_CANDIDATE
RimeGlobalCandidateWord::RimeGlobalCandidateWord(RimeEngine *engine,
const RimeCandidate &candidate,
Expand All @@ -54,6 +60,12 @@ void RimeGlobalCandidateWord::select(InputContext *inputContext) const {
}
}

void RimeGlobalCandidateWord::forget(RimeState *state) const {
#ifndef FCITX_RIME_NO_DELETE_CANDIDATE
state->deleteCandidate(idx_, /*global=*/true);
#endif
}

#endif

RimeCandidateList::RimeCandidateList(RimeEngine *engine, InputContext *ic,
Expand All @@ -62,6 +74,7 @@ RimeCandidateList::RimeCandidateList(RimeEngine *engine, InputContext *ic,
hasNext_(!context.menu.is_last_page) {
setPageable(this);
setBulk(this);
setActionable(this);

const auto &menu = context.menu;

Expand Down Expand Up @@ -138,4 +151,40 @@ const CandidateWord &RimeCandidateList::candidateFromAll(int idx) const {
}

int RimeCandidateList::totalSize() const { return -1; }

bool RimeCandidateList::hasAction(const CandidateWord &candidate) const {
#ifndef FCITX_RIME_NO_DELETE_CANDIDATE
// We can always reset rime candidate's frequency.
return true;
#else
return false;
#endif
}

std::vector<CandidateAction>
RimeCandidateList::candidateActions(const CandidateWord &candidate) const {
std::vector<CandidateAction> actions;
#ifndef FCITX_RIME_NO_DELETE_CANDIDATE
CandidateAction action;
action.setId(0);
action.setText(_("Forget word"));
actions.push_back(std::move(action));
#endif
return actions;
}

void RimeCandidateList::triggerAction(const CandidateWord &candidate, int id) {
if (id != 0) {
return;
}
if (auto state = engine_->state(ic_)) {
if (const auto *rimeCandidate =
dynamic_cast<const RimeGlobalCandidateWord *>(&candidate)) {
rimeCandidate->forget(state);
} else if (const auto *rimeCandidate =
dynamic_cast<const RimeCandidateWord *>(&candidate)) {
rimeCandidate->forget(state);
}
}
}
} // namespace fcitx
9 changes: 9 additions & 0 deletions src/rimecandidate.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include "rimeengine.h"
#include "rimestate.h"
#include <fcitx/candidateaction.h>
#include <fcitx/candidatelist.h>
#include <limits>
#include <memory>
Expand All @@ -21,6 +22,7 @@ class RimeCandidateWord : public CandidateWord {
KeySym sym, int idx);

void select(InputContext *inputContext) const override;
void forget(RimeState *state) const;

private:
RimeEngine *engine_;
Expand All @@ -35,6 +37,7 @@ class RimeGlobalCandidateWord : public CandidateWord {
int idx);

void select(InputContext *inputContext) const override;
void forget(RimeState *state) const;

private:
RimeEngine *engine_;
Expand All @@ -43,6 +46,7 @@ class RimeGlobalCandidateWord : public CandidateWord {
#endif

class RimeCandidateList final : public CandidateList,
public ActionableCandidateList,
public PageableCandidateList
#ifndef FCITX_RIME_NO_SELECT_CANDIDATE
,
Expand Down Expand Up @@ -90,6 +94,11 @@ class RimeCandidateList final : public CandidateList,
int totalSize() const override;
#endif

bool hasAction(const CandidateWord &candidate) const override;
std::vector<CandidateAction>
candidateActions(const CandidateWord &candidate) const override;
void triggerAction(const CandidateWord &candidate, int id) override;

private:
void checkIndex(int idx) const {
if (idx < 0 && idx >= size()) {
Expand Down
19 changes: 19 additions & 0 deletions src/rimestate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,25 @@ void RimeState::selectCandidate(InputContext *inputContext, int idx,
}
#endif

#ifndef FCITX_RIME_NO_DELETE_CANDIDATE
void RimeState::deleteCandidate(int idx, bool global) {
auto *api = engine_->api();
if (api->is_maintenance_mode()) {
return;
}
auto session = this->session();
if (!session) {
return;
}
if (global) {
api->delete_candidate(session, idx);
} else {
api->delete_candidate_on_current_page(session, idx);
}
updateUI(&ic_, false);
}
#endif

bool RimeState::getStatus(
const std::function<void(const RimeStatus &)> &callback) {
auto *api = engine_->api();
Expand Down
3 changes: 3 additions & 0 deletions src/rimestate.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ class RimeState : public InputContextProperty {
void keyEvent(KeyEvent &event);
#ifndef FCITX_RIME_NO_SELECT_CANDIDATE
void selectCandidate(InputContext *inputContext, int idx, bool global);
#endif
#ifndef FCITX_RIME_NO_DELETE_CANDIDATE
void deleteCandidate(int idx, bool global);
#endif
bool getStatus(const std::function<void(const RimeStatus &)> &);
void updatePreedit(InputContext *ic, const RimeContext &context);
Expand Down
Loading