Skip to content
Open
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
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions base/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ csv = "1.3.0"
default = ["use_regex_full"]
use_regex_full = ["regex"]
use_regex_lite = ["regex-lite"]
single_threaded = []

[dev-dependencies]
serde_json = "1.0"
Expand Down
10 changes: 7 additions & 3 deletions base/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ pub mod mock_time;

pub use model::get_milliseconds_since_epoch;
pub use model::Model;
pub use user_model::BorderArea;
pub use user_model::ClipboardData;
pub use user_model::UserModel;
pub use user_model::{
common::{BorderArea, ClipboardData, ModelEvent},
event::{EventEmitter, Subscription},
history::Diff,
ui::SelectedView,
UserModel,
};
14 changes: 14 additions & 0 deletions base/src/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1797,6 +1797,20 @@ impl Model {
}
}

/// Returns a list of all cells that have been changed or are being evaluated
pub fn get_changed_cells(&self) -> Vec<crate::user_model::history::CellReference> {
self.cells
.keys()
.map(
|&(sheet, row, column)| crate::user_model::history::CellReference {
sheet,
row,
column,
},
)
.collect()
}

/// Removes the content of the cell but leaves the style.
///
/// See also:
Expand Down
14 changes: 7 additions & 7 deletions base/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ pub struct DefinedName {
/// * state:
/// 18.18.68 ST_SheetState (Sheet Visibility Types)
/// hidden, veryHidden, visible
#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone)]
#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, Serialize)]
pub enum SheetState {
Visible,
Hidden,
Expand All @@ -84,7 +84,7 @@ impl Display for SheetState {
/// Represents the state of the worksheet as seen by the user. This includes
/// details such as the currently selected cell, the visible range, and the
/// position of the viewport.
#[derive(Encode, Decode, Debug, PartialEq, Clone)]
#[derive(Encode, Decode, Debug, PartialEq, Clone, Serialize)]
pub struct WorksheetView {
/// The row index of the currently selected cell.
pub row: i32,
Expand All @@ -99,7 +99,7 @@ pub struct WorksheetView {
}

/// Internal representation of a worksheet Excel object
#[derive(Encode, Decode, Debug, PartialEq, Clone)]
#[derive(Encode, Decode, Debug, PartialEq, Clone, Serialize)]
pub struct Worksheet {
pub dimension: String,
pub cols: Vec<Col>,
Expand All @@ -124,7 +124,7 @@ pub struct Worksheet {
pub type SheetData = HashMap<i32, HashMap<i32, Cell>>;

// ECMA-376-1:2016 section 18.3.1.73
#[derive(Encode, Decode, Debug, PartialEq, Clone)]
#[derive(Encode, Decode, Debug, PartialEq, Clone, Serialize)]
pub struct Row {
/// Row index
pub r: i32,
Expand All @@ -136,7 +136,7 @@ pub struct Row {
}

// ECMA-376-1:2016 section 18.3.1.13
#[derive(Encode, Decode, Debug, PartialEq, Clone)]
#[derive(Encode, Decode, Debug, PartialEq, Clone, Serialize)]
pub struct Col {
// Column definitions are defined on ranges, unlike rows which store unique, per-row entries.
/// First column affected by this record. Settings apply to column in \[min, max\] range.
Expand All @@ -159,7 +159,7 @@ pub enum CellType {
CompoundData = 128,
}

#[derive(Encode, Decode, Debug, Clone, PartialEq)]
#[derive(Encode, Decode, Debug, Clone, PartialEq, Serialize)]
pub enum Cell {
EmptyCell {
s: i32,
Expand Down Expand Up @@ -226,7 +226,7 @@ impl Default for Cell {
}
}

#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone)]
#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, Serialize)]
pub struct Comment {
pub text: String,
pub author_name: String,
Expand Down
91 changes: 71 additions & 20 deletions base/src/user_model/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use csv::{ReaderBuilder, WriterBuilder};
use serde::{Deserialize, Serialize};

use crate::{
constants::{self, LAST_COLUMN, LAST_ROW},
constants::{COLUMN_WIDTH_FACTOR, LAST_COLUMN, LAST_ROW},
expressions::{
types::{Area, CellReferenceIndex},
utils::{is_valid_column_number, is_valid_row},
Expand All @@ -16,14 +16,25 @@ use crate::{
Alignment, BorderItem, CellType, Col, HorizontalAlignment, SheetProperties, SheetState,
Style, VerticalAlignment,
},
user_model::{
event::{EventEmitter, Subscription},
history::{
CellReference, ColumnData, Diff, DiffList, DiffType, History, QueueDiffs, RowData,
},
},
utils::is_valid_hex_color,
};

use crate::user_model::history::{
ColumnData, Diff, DiffList, DiffType, History, QueueDiffs, RowData,
};

use super::border_utils::is_max_border;

/// Events that the `UserModel` can emit.
pub enum ModelEvent {
/// A list of diffs (a single user action) that can be undone/redone.
Diffs(DiffList),
/// An informational event that cells have been evaluated.
CellsEvaluated(Vec<CellReference>),
}

/// Data for the clipboard
pub type ClipboardData = HashMap<i32, HashMap<i32, ClipboardCell>>;

Expand Down Expand Up @@ -223,6 +234,7 @@ pub struct UserModel {
history: History,
send_queue: Vec<QueueDiffs>,
pause_evaluation: bool,
event_emitter: EventEmitter<ModelEvent>,
}

impl Debug for UserModel {
Expand All @@ -239,6 +251,7 @@ impl UserModel {
history: History::default(),
send_queue: vec![],
pause_evaluation: false,
event_emitter: EventEmitter::default(),
}
}

Expand All @@ -253,6 +266,7 @@ impl UserModel {
history: History::default(),
send_queue: vec![],
pause_evaluation: false,
event_emitter: EventEmitter::default(),
})
}

Expand All @@ -267,6 +281,7 @@ impl UserModel {
history: History::default(),
send_queue: vec![],
pause_evaluation: false,
event_emitter: EventEmitter::default(),
})
}

Expand Down Expand Up @@ -351,13 +366,48 @@ impl UserModel {
self.pause_evaluation = false;
}

/// Subscribes to diff events.
/// Returns a Subscription handle that automatically unsubscribes when dropped.
#[cfg(any(target_arch = "wasm32", feature = "single_threaded"))]
pub fn subscribe<F>(&self, listener: F) -> Subscription<ModelEvent>
where
F: Fn(&ModelEvent) + 'static,
{
self.event_emitter.subscribe(listener)
}

/// Subscribes to diff events.
/// Returns a Subscription handle that automatically unsubscribes when dropped.
#[cfg(not(any(target_arch = "wasm32", feature = "single_threaded")))]
pub fn subscribe<F>(&self, listener: F) -> Subscription<ModelEvent>
where
F: Fn(&ModelEvent) + Send + Sync + 'static,
{
self.event_emitter.subscribe(listener)
}

/// Forces an evaluation of the model
///
/// See also:
/// * [Model::evaluate]
/// * [UserModel::pause_evaluation]
pub fn evaluate(&mut self) {
self.model.evaluate()
// Perform evaluation
self.model.evaluate();

// Get the list of cells that were just evaluated
let evaluated_cells = self.model.get_changed_cells();

// Emit cells evaluated event if there are any cells that were evaluated
if !evaluated_cells.is_empty() {
self.event_emitter
.emit(&ModelEvent::CellsEvaluated(evaluated_cells));
}
}

/// Returns a list of all cells that have been changed or are being evaluated
pub fn get_changed_cells(&self) -> Vec<CellReference> {
self.model.get_changed_cells()
}

/// Returns the list of pending diffs and removes them from the queue
Expand Down Expand Up @@ -704,7 +754,7 @@ impl UserModel {
sheet,
row,
column,
old_style: Box::new(None),
old_style: Box::new(Some(old_style)),
});
}
}
Expand Down Expand Up @@ -734,7 +784,7 @@ impl UserModel {
sheet,
row: row.r,
column,
old_style: Box::new(None),
old_style: Box::new(Some(old_style)),
});
}
}
Expand Down Expand Up @@ -786,7 +836,7 @@ impl UserModel {
sheet,
row,
column,
old_style: Box::new(None),
old_style: Box::new(Some(old_style)),
});
}
}
Expand Down Expand Up @@ -841,7 +891,7 @@ impl UserModel {
sheet,
row,
column,
old_style: Box::new(None),
old_style: Box::new(Some(old_style)),
});
}
}
Expand Down Expand Up @@ -1680,13 +1730,13 @@ impl UserModel {
// remain in the copied area
let source = &CellReferenceIndex {
sheet,
column: *source_column,
row: *source_row,
column: *source_column,
};
let target = &CellReferenceIndex {
sheet,
column: target_column,
row: target_row,
column: target_column,
};
let new_value = if is_cut {
self.model
Expand Down Expand Up @@ -1876,6 +1926,8 @@ impl UserModel {
r#type: DiffType::Redo,
list: diff_list.clone(),
});
self.event_emitter
.emit(&ModelEvent::Diffs(diff_list.clone()));
self.history.push(diff_list);
}

Expand Down Expand Up @@ -2003,7 +2055,7 @@ impl UserModel {
}
// makes sure that the width and style is correct
if let Some(col) = &old_data.column {
let width = col.width * constants::COLUMN_WIDTH_FACTOR;
let width = col.width * COLUMN_WIDTH_FACTOR;
let style = col.style;
worksheet.set_column_width_and_style(*column, width, style)?;
}
Expand Down Expand Up @@ -2155,16 +2207,14 @@ impl UserModel {
Diff::DeleteRowStyle {
sheet,
row,
old_value,
old_value: _,
} => {
if let Some(s) = old_value.as_ref() {
self.model.set_row_style(*sheet, *row, s)?;
} else {
self.model.delete_row_style(*sheet, *row)?;
}
self.model.delete_row_style(*sheet, *row)?;
}
}
}
self.event_emitter
.emit(&ModelEvent::Diffs(diff_list.clone()));
if needs_evaluation {
self.evaluate_if_not_paused();
}
Expand Down Expand Up @@ -2366,7 +2416,8 @@ impl UserModel {
}
}
}

self.event_emitter
.emit(&ModelEvent::Diffs(diff_list.clone()));
if needs_evaluation {
self.evaluate_if_not_paused();
}
Expand Down
Loading