Skip to content

Commit 2a5cba3

Browse files
committed
feat(clipboard): allow configuration of clipboard save action directory
1 parent d60c651 commit 2a5cba3

5 files changed

Lines changed: 80 additions & 3 deletions

File tree

src/server/src/extensions/clipboard/clipboard-history-command.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,30 @@ std::vector<Preference> ClipboardHistoryCommand::preferences() const {
2626
"if your environment supports it.");
2727
preferences.emplace_back(defaultAction);
2828

29+
using Opt = Preference::DropdownData::Option;
30+
31+
auto saveDirectoryMode = Preference::makeDropdown(
32+
"saveDirectoryMode",
33+
{Opt{"Downloads folder", "downloads"}, Opt{"Home folder", "home"}, Opt{"Custom folder", "custom"}});
34+
saveDirectoryMode.setDefaultValue("downloads");
35+
saveDirectoryMode.setTitle("Save Destination");
36+
saveDirectoryMode.setDescription("Where clipboard entries are saved when using the Save to file action.");
37+
preferences.emplace_back(saveDirectoryMode);
38+
39+
auto saveCustomDirectory = Preference::directory("saveCustomDirectory");
40+
saveCustomDirectory.setTitle("Custom Save Folder");
41+
saveCustomDirectory.setDescription("Used only when Save Destination is set to Custom folder.");
42+
saveCustomDirectory.setRequired(false);
43+
saveCustomDirectory.setDefaultValue(QJsonValue::Null);
44+
preferences.emplace_back(saveCustomDirectory);
45+
46+
auto saveFileNameMode = Preference::makeDropdown(
47+
"saveFileNameMode", {Opt{"Use content preview", "content"}, Opt{"Use timestamp", "timestamp"}});
48+
saveFileNameMode.setDefaultValue("content");
49+
saveFileNameMode.setTitle("Save Filename");
50+
saveFileNameMode.setDescription(
51+
"Choose whether generated save filenames come from the content or from timestamp.");
52+
preferences.emplace_back(saveFileNameMode);
53+
2954
return preferences;
3055
}

src/server/src/extensions/clipboard/history/clipboard-history-actions.hpp

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,24 @@ class CopyClipboardSelection : public AbstractAction {
4747

4848
class SaveClipboardSelectionToFileAction : public AbstractAction {
4949
ClipboardHistoryEntry m_entry;
50+
QString m_saveDirectoryMode;
51+
QString m_saveCustomDirectory;
52+
QString m_saveFileNameMode;
53+
54+
QString kindToken() const {
55+
switch (m_entry.kind) {
56+
case ClipboardOfferKind::Image:
57+
return "image";
58+
case ClipboardOfferKind::File:
59+
return "file";
60+
case ClipboardOfferKind::Link:
61+
return "link";
62+
case ClipboardOfferKind::Text:
63+
return "text";
64+
default:
65+
return "entry";
66+
}
67+
}
5068

5169
static QStringList uriLines(const QByteArray &data) {
5270
QString const text = QString::fromUtf8(data);
@@ -117,6 +135,11 @@ class SaveClipboardSelectionToFileAction : public AbstractAction {
117135
}
118136

119137
QString defaultFileStem(const QByteArray &data) const {
138+
if (m_saveFileNameMode == "timestamp") {
139+
auto dt = QDateTime::fromSecsSinceEpoch(m_entry.updatedAt);
140+
return QString("clipboard-%1-%2").arg(kindToken()).arg(dt.toString("yyyyMMdd-HHmmss"));
141+
}
142+
120143
if (m_entry.kind == ClipboardOfferKind::Image) {
121144
auto dt = QDateTime::fromSecsSinceEpoch(m_entry.updatedAt);
122145
return QString("clipboard-image-%1").arg(dt.toString("yyyyMMdd-HHmmss"));
@@ -144,6 +167,17 @@ class SaveClipboardSelectionToFileAction : public AbstractAction {
144167
}
145168

146169
QString saveDirectoryPath() const {
170+
if (m_saveDirectoryMode == "custom") {
171+
QString const custom = m_saveCustomDirectory.trimmed();
172+
if (!custom.isEmpty()) return custom;
173+
}
174+
175+
if (m_saveDirectoryMode == "home") {
176+
auto folder = homeDir();
177+
if (!folder.empty()) return QString::fromStdString(folder.string());
178+
return QDir::homePath();
179+
}
180+
147181
auto folder = downloadsFolder();
148182
std::error_code ec;
149183
if (folder.empty() || !std::filesystem::is_directory(folder, ec)) { folder = homeDir(); }
@@ -209,8 +243,12 @@ class SaveClipboardSelectionToFileAction : public AbstractAction {
209243
}
210244

211245
public:
212-
explicit SaveClipboardSelectionToFileAction(const ClipboardHistoryEntry &entry)
213-
: AbstractAction("Save to file", BuiltinIcon::SaveDocument), m_entry(entry) {}
246+
SaveClipboardSelectionToFileAction(const ClipboardHistoryEntry &entry, QString saveDirectoryMode,
247+
QString saveCustomDirectory, QString saveFileNameMode)
248+
: AbstractAction("Save to file", BuiltinIcon::SaveDocument), m_entry(entry),
249+
m_saveDirectoryMode(std::move(saveDirectoryMode)),
250+
m_saveCustomDirectory(std::move(saveCustomDirectory)),
251+
m_saveFileNameMode(std::move(saveFileNameMode)) {}
214252
};
215253

216254
class RemoveSelectionAction : public AbstractAction {

src/server/src/qml/clipboard-history-model.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,8 @@ std::unique_ptr<ActionPanelState> ClipboardHistoryModel::createActionPanel(int,
116116
auto dangerSection = panel->createSection();
117117
toolsSection->addAction(pin);
118118
if (isCopyable) {
119-
auto saveToFile = new SaveClipboardSelectionToFileAction(entry);
119+
auto saveToFile = new SaveClipboardSelectionToFileAction(entry, m_saveDirectoryMode,
120+
m_saveCustomDirectory, m_saveFileNameMode);
120121
saveToFile->setShortcut(Keybind::SaveAction);
121122
toolsSection->addAction(saveToFile);
122123
}

src/server/src/qml/clipboard-history-model.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ class ClipboardHistoryModel : public CommandListModel {
1717

1818
void setEntries(const PaginatedResponse<ClipboardHistoryEntry> &page);
1919
void setDefaultAction(DefaultAction action) { m_defaultAction = action; }
20+
void setSaveDirectoryMode(QString value) { m_saveDirectoryMode = std::move(value); }
21+
void setSaveCustomDirectory(QString value) { m_saveCustomDirectory = std::move(value); }
22+
void setSaveFileNameMode(QString value) { m_saveFileNameMode = std::move(value); }
2023
void resetSelectionOnNextUpdate() { setSelectFirstOnReset(true); }
2124
void setFilter(const QString &text) override {}
2225
QString searchPlaceholder() const override { return QStringLiteral("Browse clipboard history..."); }
@@ -40,4 +43,7 @@ class ClipboardHistoryModel : public CommandListModel {
4043

4144
std::vector<ClipboardHistoryEntry> m_entries;
4245
DefaultAction m_defaultAction = DefaultAction::Copy;
46+
QString m_saveDirectoryMode = "downloads";
47+
QString m_saveCustomDirectory;
48+
QString m_saveFileNameMode = "content";
4349
};

src/server/src/qml/clipboard-history-view-host.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,15 @@ void ClipboardHistoryViewHost::initialize() {
7474

7575
auto preferences = command()->preferenceValues();
7676
auto defaultActionStr = preferences.value("defaultAction").toString();
77+
auto saveDirectoryMode = preferences.value("saveDirectoryMode").toString();
78+
auto saveCustomDirectory = preferences.value("saveCustomDirectory").toString();
79+
auto saveFileNameMode = preferences.value("saveFileNameMode").toString();
80+
7781
m_model->setDefaultAction(defaultActionStr == "paste" ? ClipboardHistoryModel::DefaultAction::Paste
7882
: ClipboardHistoryModel::DefaultAction::Copy);
83+
m_model->setSaveDirectoryMode(saveDirectoryMode.isEmpty() ? "downloads" : saveDirectoryMode);
84+
m_model->setSaveCustomDirectory(saveCustomDirectory);
85+
m_model->setSaveFileNameMode(saveFileNameMode.isEmpty() ? "content" : saveFileNameMode);
7986

8087
setSearchPlaceholderText("Browse clipboard history...");
8188

0 commit comments

Comments
 (0)