Skip to content
This repository was archived by the owner on Aug 25, 2024. It is now read-only.

Commit 7450f65

Browse files
committed
improve copy,pin,delete icon, add UtilsTest.cs
1 parent 2a64332 commit 7450f65

File tree

10 files changed

+226
-91
lines changed

10 files changed

+226
-91
lines changed

build/Program.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ public override void Run(BuildContext context)
116116
@"Clipboar.+\.dll|"
117117
+ @".+\.png|"
118118
+ @"Dapper\.dll|Svg\.dll|Material\.Icons\.dll|"
119+
+ @"Material.Icons.WPF\.dll|"
119120
+ @"ExCSS\.dll|"
120121
+ @"plugin\.json|H\.InputSimulator\.dll|"
121122
+ @"SQLitePCLRaw.+\.dll|Microsoft.+(S|s)qlite\.dll";
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
using System.Text;
2+
using System.Text.Unicode;
3+
using Xunit.Abstractions;
4+
5+
namespace ClipboardR.Core.Test;
6+
7+
public class UtilsTest
8+
{
9+
private readonly ITestOutputHelper _testOutputHelper;
10+
11+
public UtilsTest(ITestOutputHelper testOutputHelper)
12+
{
13+
_testOutputHelper = testOutputHelper;
14+
}
15+
16+
[Theory]
17+
[InlineData("QQ.exe", 1)]
18+
[InlineData("", 0)]
19+
[InlineData("在池台的正中,像当初的怀中,隔太多春秋会不能相拥", 24)]
20+
[InlineData(
21+
"Out of the tens of thousands of people, we are fortunate enough to "
22+
+ "meet each other, and in an instant, there is a profound clarity and understanding.",
23+
27
24+
)]
25+
[InlineData("你好,~", 4)]
26+
[InlineData("你好,Hello啊.\nabc‘ def(), qwe'", 9)]
27+
public void TestWordsCount(string s, int n)
28+
{
29+
var nw = Utils.CountWordsEn(s) + Utils.CountWordsCn(s);
30+
_testOutputHelper.WriteLine($"En:{Utils.CountWordsEn(s)}, Cn: {Utils.CountWordsCn(s)}");
31+
_testOutputHelper.WriteLine($"{n}:{nw}");
32+
Assert.True(n == nw);
33+
}
34+
}

src/ClipboardR.Core/DbHelper.cs

Lines changed: 63 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -13,34 +13,34 @@ public class DbHelper
1313
private string SqlCheckTableRecord = "SELECT name from sqlite_master WHERE name='record'";
1414

1515
private string SqlCreateDb = """
16-
CREATE TABLE assets (
17-
id INTEGER NOT NULL UNIQUE,
18-
data_b64 TEXT,
19-
md5 TEXT UNIQUE ,
20-
PRIMARY KEY("id" AUTOINCREMENT)
21-
);
16+
CREATE TABLE assets (
17+
id INTEGER NOT NULL UNIQUE,
18+
data_b64 TEXT,
19+
md5 TEXT UNIQUE ,
20+
PRIMARY KEY("id" AUTOINCREMENT)
21+
);
2222
23-
CREATE TABLE "record" (
24-
"id" INTEGER NOT NULL UNIQUE,
25-
"hash_id" TEXT UNIQUE,
26-
"data_md5" TEXT,
27-
"text" TEXT,
28-
"display_title" TEXT,
29-
"senderapp" TEXT,
30-
"icon_path" TEXT,
31-
"icon_md5" TEXT,
32-
"preview_image_path" TEXT,
33-
"content_type" INTEGER,
34-
"score" INTEGER,
35-
"init_score" INTEGER,
36-
"time" TEXT,
37-
"create_time" TEXT,
38-
"pined" INTEGER,
39-
PRIMARY KEY("id" AUTOINCREMENT),
40-
FOREIGN KEY("icon_md5") REFERENCES "assets"("md5"),
41-
FOREIGN KEY("data_md5") REFERENCES "assets"("md5") ON DELETE CASCADE
42-
);
43-
""";
23+
CREATE TABLE "record" (
24+
"id" INTEGER NOT NULL UNIQUE,
25+
"hash_id" TEXT UNIQUE,
26+
"data_md5" TEXT,
27+
"text" TEXT,
28+
"display_title" TEXT,
29+
"senderapp" TEXT,
30+
"icon_path" TEXT,
31+
"icon_md5" TEXT,
32+
"preview_image_path" TEXT,
33+
"content_type" INTEGER,
34+
"score" INTEGER,
35+
"init_score" INTEGER,
36+
"time" TEXT,
37+
"create_time" TEXT,
38+
"pined" INTEGER,
39+
PRIMARY KEY("id" AUTOINCREMENT),
40+
FOREIGN KEY("icon_md5") REFERENCES "assets"("md5"),
41+
FOREIGN KEY("data_md5") REFERENCES "assets"("md5") ON DELETE CASCADE
42+
);
43+
""";
4444

4545
public DbHelper(SqliteConnection connection)
4646
{
@@ -131,6 +131,7 @@ await Connection.ExecuteAsync(
131131
sql = "PRAGMA foreign_keys = ON; DELETE FROM assets WHERE md5=@DataMd5;";
132132
await Connection.ExecuteAsync(sql, new { DataMd5 = dataMd5 });
133133
}
134+
134135
CloseIfNotKeep();
135136
}
136137

@@ -141,28 +142,43 @@ public async void DeleteAllRecords()
141142
CreateDb();
142143
}
143144

144-
public async void PinOneRecord(ClipboardData clipboardData)
145+
public async void PinOneRecord(ClipboardData data)
145146
{
146-
var sql = "UPDATE record SET pined=@Pin WHERE hash_id=@HashId";
147+
var sql = "INSERT OR IGNORE INTO assets(data_b64, md5) VALUES (@DataB64, @Md5);";
148+
var iconB64 = data.Icon.ToBase64();
149+
var iconMd5 = iconB64.GetMd5();
150+
var rows = await Connection.ExecuteAsync(
151+
sql,
152+
new List<Assets>
153+
{
154+
new() { DataB64 = iconB64, Md5 = iconMd5 },
155+
}
156+
);
157+
sql = "UPDATE record SET pined=@Pin, icon_md5=@IconMd5 WHERE hash_id=@HashId";
147158
await Connection.ExecuteAsync(
148159
sql,
149-
new { Pin = clipboardData.Pined, HashId = clipboardData.HashId }
160+
new
161+
{
162+
Pin = data.Pined,
163+
HashId = data.HashId,
164+
IconMd5 = iconMd5
165+
}
150166
);
151167
CloseIfNotKeep();
152168
}
153169

154170
public async Task<LinkedList<ClipboardData>> GetAllRecord()
155171
{
156172
var sql = """
157-
SELECT r.id as Id, a.data_b64 as DataMd5, r.text as Text, r.display_title as DisplayTitle,
158-
r.senderapp as SenderApp, r.icon_path as IconPath, b.data_b64 as IconMd5,
159-
r.preview_image_path as PreviewImagePath, r.content_type as ContentType,
160-
r.score as Score, r.init_score as InitScore, r.time as Time,
161-
r.create_time as CreateTime, r.pined as Pined, r.hash_id as HashId
162-
FROM record r
163-
LEFT JOIN assets a ON r.data_md5=a.md5
164-
LEFT JOIN assets b ON r.icon_md5=b.md5;
165-
""";
173+
SELECT r.id as Id, a.data_b64 as DataMd5, r.text as Text, r.display_title as DisplayTitle,
174+
r.senderapp as SenderApp, r.icon_path as IconPath, b.data_b64 as IconMd5,
175+
r.preview_image_path as PreviewImagePath, r.content_type as ContentType,
176+
r.score as Score, r.init_score as InitScore, r.time as Time,
177+
r.create_time as CreateTime, r.pined as Pined, r.hash_id as HashId
178+
FROM record r
179+
LEFT JOIN assets a ON r.data_md5=a.md5
180+
LEFT JOIN assets b ON r.icon_md5=b.md5;
181+
""";
166182
var results = await Connection.QueryAsync<Record>(sql);
167183
LinkedList<ClipboardData> allRecord = new(results.Select(Record.ToClipboardData));
168184
CloseIfNotKeep();
@@ -172,10 +188,10 @@ FROM record r
172188
public async void DeleteRecordByKeepTime(int contentType, int keepTime)
173189
{
174190
var sql = """
175-
DELETE FROM record
176-
WHERE strftime('%s', 'now') - strftime('%s', create_time) > @KeepTime*3600
177-
AND content_type=@ContentType;
178-
""";
191+
DELETE FROM record
192+
WHERE strftime('%s', 'now') - strftime('%s', create_time) > @KeepTime*3600
193+
AND content_type=@ContentType;
194+
""";
179195
var r = await Connection.ExecuteAsync(
180196
sql,
181197
new { KeepTime = keepTime, ContentType = contentType }
@@ -227,17 +243,21 @@ public class Record
227243
public int Score { get; set; }
228244
public int InitScore { get; set; }
229245
public DateTime _time;
246+
230247
public string Time
231248
{
232249
get => _time.ToString("O");
233250
set => _time = DateTime.Parse(value);
234251
}
252+
235253
public DateTime _create_time;
254+
236255
public string CreateTime
237256
{
238257
get => _create_time.ToString("O");
239258
set => _create_time = DateTime.Parse(value);
240259
}
260+
241261
public bool Pined { get; set; }
242262

243263
public static Record FromClipboardData(ClipboardData data)

src/ClipboardR.Core/Utils.cs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
namespace ClipboardR.Core;
1+
using System.Text;
2+
using System.Text.RegularExpressions;
3+
4+
namespace ClipboardR.Core;
25

36
public static class Utils
47
{
@@ -12,6 +15,26 @@ public static string RandomString(int length)
1215
);
1316
}
1417

18+
public static int CountWords(string s)
19+
{
20+
return CountWordsCn(s) + CountWordsEn(s);
21+
}
22+
23+
public static int CountWordsCn(string s)
24+
{
25+
var nCn = (Encoding.UTF8.GetByteCount(s) - s.Length) / 2;
26+
// var nCn = s.ToCharArray().Count(c => c >= 0x4E00 && c <= 0x9FFF);
27+
return nCn;
28+
}
29+
30+
public static int CountWordsEn(string s)
31+
{
32+
// // TODO: count more reasonable
33+
s = string.Join("", s.Where(c => c < 0x4E00));
34+
var collection = Regex.Matches(s, @"[\S]+");
35+
return collection.Count;
36+
}
37+
1538
public static string GetGuid()
1639
{
1740
return Guid.NewGuid().ToString("D");

src/ClipboardR.Panels.Test/ClipboardR.Panels.Test.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,8 @@
1111
<ProjectReference Include="..\ClipboardR.Panels\ClipboardR.Panels.csproj" />
1212
</ItemGroup>
1313

14+
<ItemGroup>
15+
<PackageReference Include="Material.Icons.WPF" Version="2.0.0" />
16+
</ItemGroup>
17+
1418
</Project>

src/ClipboardR.Panels.Test/MainWindow.xaml

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,15 @@
88
mc:Ignorable="d"
99
Title="MainWindow" Height="450" Width="800">
1010
<Grid>
11-
<panels:SettingsPanel
12-
x:Name="SettingsPanel"
13-
/>
14-
11+
<TabControl
12+
SelectedIndex="1">
13+
<TabItem Header="Settings">
14+
<panels:SettingsPanel
15+
x:Name="SettingsPanel" />
16+
</TabItem>
17+
<TabItem Header="Preview">
18+
<panels:PreviewPanel />
19+
</TabItem>
20+
</TabControl>
1521
</Grid>
16-
</Window>
22+
</Window>

0 commit comments

Comments
 (0)