wip: add clipboard support
This commit is contained in:
@@ -194,6 +194,27 @@ static void wp_sync_paragraph_count(WordProcessorState* wp) {
|
||||
}
|
||||
}
|
||||
|
||||
static int wp_count_newline_chars(const char* text, int len) {
|
||||
if (len < 0) return -1;
|
||||
if (len > 0 && text == nullptr) return -1;
|
||||
|
||||
int count = 0;
|
||||
for (int i = 0; i < len; i++) {
|
||||
if (text[i] == '\0') return -1;
|
||||
if (text[i] == '\n') count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
static int wp_count_newlines_in_range(WordProcessorState* wp, int start, int end) {
|
||||
int count = 0;
|
||||
for (int i = start; i < end; i++) {
|
||||
if (wp_char_at(wp, i) == '\n')
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
static void wp_on_insert_newline(WordProcessorState* wp, int abs_pos) {
|
||||
if (wp->paragraph_count >= WP_MAX_PARAGRAPHS) return;
|
||||
int para = wp_find_paragraph_at(wp, abs_pos);
|
||||
@@ -1115,6 +1136,46 @@ void wp_delete_selection(WordProcessorState* wp) {
|
||||
wp_clear_selection(wp);
|
||||
}
|
||||
|
||||
char* wp_selection_plain_text_alloc(WordProcessorState* wp, int* out_len) {
|
||||
if (out_len) *out_len = 0;
|
||||
if (wp == nullptr || !wp->has_selection) return nullptr;
|
||||
|
||||
int sel_s, sel_e;
|
||||
wp_sel_range(wp, &sel_s, &sel_e);
|
||||
int len = sel_e - sel_s;
|
||||
if (len <= 0) return nullptr;
|
||||
|
||||
char* text = (char*)montauk::malloc(len + 1);
|
||||
if (text == nullptr) return nullptr;
|
||||
|
||||
for (int i = 0; i < len; i++)
|
||||
text[i] = wp_char_at(wp, sel_s + i);
|
||||
text[len] = '\0';
|
||||
|
||||
if (out_len) *out_len = len;
|
||||
return text;
|
||||
}
|
||||
|
||||
bool wp_insert_text(WordProcessorState* wp, const char* text, int len) {
|
||||
int newline_count = wp_count_newline_chars(text, len);
|
||||
if (wp == nullptr || newline_count < 0) return false;
|
||||
if (len == 0) return true;
|
||||
if (wp->cursor_run < 0 || wp->cursor_run >= wp->run_count) return false;
|
||||
if (wp->total_text_len + len > WP_MAX_TEXT - 1) return false;
|
||||
if (wp->paragraph_count + newline_count > WP_MAX_PARAGRAPHS) return false;
|
||||
|
||||
StyledRun* cur = &wp->runs[wp->cursor_run];
|
||||
int extra_runs = 0;
|
||||
if (!wp_same_style(cur, wp->cur_font_id, wp->cur_size, wp->cur_flags)) {
|
||||
extra_runs = (wp->cursor_offset == 0 || wp->cursor_offset == cur->len) ? 1 : 2;
|
||||
}
|
||||
if (wp->run_count + extra_runs > WP_MAX_RUNS) return false;
|
||||
|
||||
for (int i = 0; i < len; i++)
|
||||
wp_insert_char(wp, text[i]);
|
||||
return true;
|
||||
}
|
||||
|
||||
void wp_recompute_wrap(WordProcessorState* wp, int content_w, int layout_dpi) {
|
||||
int wrap_width = content_w - WP_MARGIN * 2 - WP_SCROLLBAR_W;
|
||||
if (wrap_width < 50) wrap_width = 50;
|
||||
@@ -1664,6 +1725,38 @@ static bool wp_restore_snapshot(WordProcessorState* wp, const UndoSnapshot* snap
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wp_replace_selection_with_text(WordProcessorState* wp, const char* text, int len) {
|
||||
int newline_count = wp_count_newline_chars(text, len);
|
||||
if (wp == nullptr || newline_count < 0) return false;
|
||||
|
||||
int sel_len = 0;
|
||||
int sel_newlines = 0;
|
||||
if (wp->has_selection) {
|
||||
int sel_s, sel_e;
|
||||
wp_sel_range(wp, &sel_s, &sel_e);
|
||||
sel_len = sel_e - sel_s;
|
||||
sel_newlines = wp_count_newlines_in_range(wp, sel_s, sel_e);
|
||||
}
|
||||
|
||||
if (wp->total_text_len - sel_len + len > WP_MAX_TEXT - 1)
|
||||
return false;
|
||||
if (wp->paragraph_count - sel_newlines + newline_count > WP_MAX_PARAGRAPHS)
|
||||
return false;
|
||||
|
||||
UndoSnapshot snap = {};
|
||||
if (!wp_capture_snapshot(wp, &snap))
|
||||
return false;
|
||||
|
||||
if (wp->has_selection)
|
||||
wp_delete_selection(wp);
|
||||
|
||||
bool ok = wp_insert_text(wp, text, len);
|
||||
if (!ok)
|
||||
wp_restore_snapshot(wp, &snap);
|
||||
wp_free_snapshot(&snap);
|
||||
return ok;
|
||||
}
|
||||
|
||||
void wp_save_file(WordProcessorState* wp) {
|
||||
if (wp->filepath[0] == '\0') {
|
||||
wp_open_save_pathbar(wp);
|
||||
|
||||
Reference in New Issue
Block a user