From bb06f63fbc73845f86603e22e49017d159a67b48 Mon Sep 17 00:00:00 2001 From: Andreas Buchen Date: Wed, 21 Aug 2024 07:21:46 +0200 Subject: [PATCH] Added identifier to dashboard Enables to identify dashboards in configuration (say navigation bar) without relying on the relative position of the dashboard --- .../ui/views/dashboard/DashboardView.java | 3 +- .../views/dashboard/NewDashboardDialog.java | 4 +- .../model/proto/v1/ClientProtos.java | 102 ++++++------- .../portfolio/model/proto/v1/PDashboard.java | 136 ++++++++++++++++++ .../model/proto/v1/PDashboardOrBuilder.java | 12 ++ .../name/abuchen/portfolio/model/Client.java | 2 +- .../portfolio/model/ClientFactory.java | 17 ++- .../abuchen/portfolio/model/Dashboard.java | 23 ++- .../portfolio/model/ProtobufWriter.java | 2 + .../name/abuchen/portfolio/model/client.proto | 1 + 10 files changed, 244 insertions(+), 58 deletions(-) diff --git a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/dashboard/DashboardView.java b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/dashboard/DashboardView.java index 251710691a..27dd1cc6d5 100644 --- a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/dashboard/DashboardView.java +++ b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/dashboard/DashboardView.java @@ -8,6 +8,7 @@ import java.util.List; import java.util.Map; import java.util.StringJoiner; +import java.util.UUID; import java.util.concurrent.BlockingQueue; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -923,7 +924,7 @@ private void deleteColumn(Composite columnControl) private Dashboard createDefaultDashboard() { - Dashboard newDashboard = new Dashboard(); + Dashboard newDashboard = new Dashboard(UUID.randomUUID().toString()); newDashboard.setName(Messages.LabelDashboard); NewDashboardDialog.buildIndicatorDashboard(newDashboard); diff --git a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/dashboard/NewDashboardDialog.java b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/dashboard/NewDashboardDialog.java index ec6d425d32..3f244d0ccc 100644 --- a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/dashboard/NewDashboardDialog.java +++ b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/dashboard/NewDashboardDialog.java @@ -1,5 +1,7 @@ package name.abuchen.portfolio.ui.views.dashboard; +import java.util.UUID; + import org.eclipse.jface.dialogs.Dialog; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionListener; @@ -87,7 +89,7 @@ protected final Control createDialogArea(Composite parent) public Dashboard createDashboard() { - Dashboard newDashboard = new Dashboard(); + Dashboard newDashboard = new Dashboard(UUID.randomUUID().toString()); newDashboard.setName(selectedName); switch (selectedTemplate) diff --git a/name.abuchen.portfolio/protos/name/abuchen/portfolio/model/proto/v1/ClientProtos.java b/name.abuchen.portfolio/protos/name/abuchen/portfolio/model/proto/v1/ClientProtos.java index e0c1c90004..5b2a815280 100644 --- a/name.abuchen.portfolio/protos/name/abuchen/portfolio/model/proto/v1/ClientProtos.java +++ b/name.abuchen.portfolio/protos/name/abuchen/portfolio/model/proto/v1/ClientProtos.java @@ -290,59 +290,59 @@ public static void registerAllExtensions( "\005\022/\n\004data\030\010 \003(\0132!.name.abuchen.portfolio" + ".PKeyValue\022A\n\013assignments\030\t \003(\0132,.name.a" + "buchen.portfolio.PTaxonomy.AssignmentB\013\n" + - "\t_parentIdB\007\n\005_noteB\t\n\007_source\"\343\003\n\nPDash" + + "\t_parentIdB\007\n\005_noteB\t\n\007_source\"\357\003\n\nPDash" + "board\022\014\n\004name\030\001 \001(\t\022L\n\rconfiguration\030\002 \003" + "(\01325.name.abuchen.portfolio.PDashboard.C" + "onfigurationEntry\022:\n\007columns\030\003 \003(\0132).nam" + - "e.abuchen.portfolio.PDashboard.Column\032\260\001" + - "\n\006Widget\022\014\n\004type\030\001 \001(\t\022\r\n\005label\030\002 \001(\t\022S\n" + - "\rconfiguration\030\003 \003(\0132<.name.abuchen.port" + - "folio.PDashboard.Widget.ConfigurationEnt" + - "ry\0324\n\022ConfigurationEntry\022\013\n\003key\030\001 \001(\t\022\r\n" + - "\005value\030\002 \001(\t:\0028\001\032T\n\006Column\022\016\n\006weight\030\001 \001" + - "(\005\022:\n\007widgets\030\002 \003(\0132).name.abuchen.portf" + - "olio.PDashboard.Widget\0324\n\022ConfigurationE" + - "ntry\022\013\n\003key\030\001 \001(\t\022\r\n\005value\030\002 \001(\t:\0028\001\"+\n\t" + - "PBookmark\022\r\n\005label\030\001 \001(\t\022\017\n\007pattern\030\002 \001(" + - "\t\"\307\001\n\016PAttributeType\022\n\n\002id\030\001 \001(\t\022\014\n\004name" + - "\030\002 \001(\t\022\023\n\013columnLabel\030\003 \001(\t\022\023\n\006source\030\004 " + - "\001(\tH\000\210\001\001\022\016\n\006target\030\005 \001(\t\022\014\n\004type\030\006 \001(\t\022\026" + - "\n\016converterClass\030\007 \001(\t\0220\n\nproperties\030\010 \001" + - "(\0132\034.name.abuchen.portfolio.PMapB\t\n\007_sou" + - "rce\"J\n\021PConfigurationSet\022\013\n\003key\030\001 \001(\t\022\014\n" + - "\004uuid\030\002 \001(\t\022\014\n\004name\030\003 \001(\t\022\014\n\004data\030\004 \001(\t\"" + - "\307\001\n\tPSettings\0224\n\tbookmarks\030\001 \003(\0132!.name." + - "abuchen.portfolio.PBookmark\022>\n\016attribute" + - "Types\030\002 \003(\0132&.name.abuchen.portfolio.PAt" + - "tributeType\022D\n\021configurationSets\030\003 \003(\0132)" + - ".name.abuchen.portfolio.PConfigurationSe" + - "t\"\233\005\n\007PClient\022\017\n\007version\030\001 \001(\005\0225\n\nsecuri" + - "ties\030\002 \003(\0132!.name.abuchen.portfolio.PSec" + - "urity\0222\n\010accounts\030\003 \003(\0132 .name.abuchen.p" + - "ortfolio.PAccount\0226\n\nportfolios\030\004 \003(\0132\"." + - "name.abuchen.portfolio.PPortfolio\022:\n\014tra" + - "nsactions\030\005 \003(\0132$.name.abuchen.portfolio" + - ".PTransaction\0226\n\005plans\030\006 \003(\0132\'.name.abuc" + - "hen.portfolio.PInvestmentPlan\0226\n\nwatchli" + - "sts\030\007 \003(\0132\".name.abuchen.portfolio.PWatc" + - "hlist\0225\n\ntaxonomies\030\010 \003(\0132!.name.abuchen" + - ".portfolio.PTaxonomy\0226\n\ndashboards\030\t \003(\013" + - "2\".name.abuchen.portfolio.PDashboard\022C\n\n" + - "properties\030\n \003(\0132/.name.abuchen.portfoli" + - "o.PClient.PropertiesEntry\0223\n\010settings\030\013 " + - "\001(\0132!.name.abuchen.portfolio.PSettings\022\024" + - "\n\014baseCurrency\030\014 \001(\t\0321\n\017PropertiesEntry\022" + - "\013\n\003key\030\001 \001(\t\022\r\n\005value\030\002 \001(\t:\0028\001\"S\n\rPExch" + - "angeRate\022\014\n\004date\030\001 \001(\003\0224\n\005value\030\002 \001(\0132%." + - "name.abuchen.portfolio.PDecimalValue\"\203\001\n" + - "\027PExchangeRateTimeSeries\022\024\n\014baseCurrency" + - "\030\001 \001(\t\022\024\n\014termCurrency\030\002 \001(\t\022<\n\rexchange" + - "Rates\030\003 \003(\0132%.name.abuchen.portfolio.PEx" + - "changeRate\"a\n\010PECBData\022\024\n\014lastModified\030\001" + - " \001(\003\022?\n\006series\030\002 \003(\0132/.name.abuchen.port" + - "folio.PExchangeRateTimeSeriesB7\n%name.ab" + - "uchen.portfolio.model.proto.v1B\014ClientPr" + - "otosP\001b\006proto3" + "e.abuchen.portfolio.PDashboard.Column\022\n\n" + + "\002id\030\004 \001(\t\032\260\001\n\006Widget\022\014\n\004type\030\001 \001(\t\022\r\n\005la" + + "bel\030\002 \001(\t\022S\n\rconfiguration\030\003 \003(\0132<.name." + + "abuchen.portfolio.PDashboard.Widget.Conf" + + "igurationEntry\0324\n\022ConfigurationEntry\022\013\n\003" + + "key\030\001 \001(\t\022\r\n\005value\030\002 \001(\t:\0028\001\032T\n\006Column\022\016" + + "\n\006weight\030\001 \001(\005\022:\n\007widgets\030\002 \003(\0132).name.a" + + "buchen.portfolio.PDashboard.Widget\0324\n\022Co" + + "nfigurationEntry\022\013\n\003key\030\001 \001(\t\022\r\n\005value\030\002" + + " \001(\t:\0028\001\"+\n\tPBookmark\022\r\n\005label\030\001 \001(\t\022\017\n\007" + + "pattern\030\002 \001(\t\"\307\001\n\016PAttributeType\022\n\n\002id\030\001" + + " \001(\t\022\014\n\004name\030\002 \001(\t\022\023\n\013columnLabel\030\003 \001(\t\022" + + "\023\n\006source\030\004 \001(\tH\000\210\001\001\022\016\n\006target\030\005 \001(\t\022\014\n\004" + + "type\030\006 \001(\t\022\026\n\016converterClass\030\007 \001(\t\0220\n\npr" + + "operties\030\010 \001(\0132\034.name.abuchen.portfolio." + + "PMapB\t\n\007_source\"J\n\021PConfigurationSet\022\013\n\003" + + "key\030\001 \001(\t\022\014\n\004uuid\030\002 \001(\t\022\014\n\004name\030\003 \001(\t\022\014\n" + + "\004data\030\004 \001(\t\"\307\001\n\tPSettings\0224\n\tbookmarks\030\001" + + " \003(\0132!.name.abuchen.portfolio.PBookmark\022" + + ">\n\016attributeTypes\030\002 \003(\0132&.name.abuchen.p" + + "ortfolio.PAttributeType\022D\n\021configuration" + + "Sets\030\003 \003(\0132).name.abuchen.portfolio.PCon" + + "figurationSet\"\233\005\n\007PClient\022\017\n\007version\030\001 \001" + + "(\005\0225\n\nsecurities\030\002 \003(\0132!.name.abuchen.po" + + "rtfolio.PSecurity\0222\n\010accounts\030\003 \003(\0132 .na" + + "me.abuchen.portfolio.PAccount\0226\n\nportfol" + + "ios\030\004 \003(\0132\".name.abuchen.portfolio.PPort" + + "folio\022:\n\014transactions\030\005 \003(\0132$.name.abuch" + + "en.portfolio.PTransaction\0226\n\005plans\030\006 \003(\013" + + "2\'.name.abuchen.portfolio.PInvestmentPla" + + "n\0226\n\nwatchlists\030\007 \003(\0132\".name.abuchen.por" + + "tfolio.PWatchlist\0225\n\ntaxonomies\030\010 \003(\0132!." + + "name.abuchen.portfolio.PTaxonomy\0226\n\ndash" + + "boards\030\t \003(\0132\".name.abuchen.portfolio.PD" + + "ashboard\022C\n\nproperties\030\n \003(\0132/.name.abuc" + + "hen.portfolio.PClient.PropertiesEntry\0223\n" + + "\010settings\030\013 \001(\0132!.name.abuchen.portfolio" + + ".PSettings\022\024\n\014baseCurrency\030\014 \001(\t\0321\n\017Prop" + + "ertiesEntry\022\013\n\003key\030\001 \001(\t\022\r\n\005value\030\002 \001(\t:" + + "\0028\001\"S\n\rPExchangeRate\022\014\n\004date\030\001 \001(\003\0224\n\005va" + + "lue\030\002 \001(\0132%.name.abuchen.portfolio.PDeci" + + "malValue\"\203\001\n\027PExchangeRateTimeSeries\022\024\n\014" + + "baseCurrency\030\001 \001(\t\022\024\n\014termCurrency\030\002 \001(\t" + + "\022<\n\rexchangeRates\030\003 \003(\0132%.name.abuchen.p" + + "ortfolio.PExchangeRate\"a\n\010PECBData\022\024\n\014la" + + "stModified\030\001 \001(\003\022?\n\006series\030\002 \003(\0132/.name." + + "abuchen.portfolio.PExchangeRateTimeSerie" + + "sB7\n%name.abuchen.portfolio.model.proto." + + "v1B\014ClientProtosP\001b\006proto3" }; descriptor = com.google.protobuf.Descriptors.FileDescriptor .internalBuildGeneratedFileFrom(descriptorData, @@ -457,7 +457,7 @@ public static void registerAllExtensions( internal_static_name_abuchen_portfolio_PDashboard_fieldAccessorTable = new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( internal_static_name_abuchen_portfolio_PDashboard_descriptor, - new java.lang.String[] { "Name", "Configuration", "Columns", }); + new java.lang.String[] { "Name", "Configuration", "Columns", "Id", }); internal_static_name_abuchen_portfolio_PDashboard_Widget_descriptor = internal_static_name_abuchen_portfolio_PDashboard_descriptor.getNestedTypes().get(0); internal_static_name_abuchen_portfolio_PDashboard_Widget_fieldAccessorTable = new diff --git a/name.abuchen.portfolio/protos/name/abuchen/portfolio/model/proto/v1/PDashboard.java b/name.abuchen.portfolio/protos/name/abuchen/portfolio/model/proto/v1/PDashboard.java index dd8404837b..4a87ab4c89 100644 --- a/name.abuchen.portfolio/protos/name/abuchen/portfolio/model/proto/v1/PDashboard.java +++ b/name.abuchen.portfolio/protos/name/abuchen/portfolio/model/proto/v1/PDashboard.java @@ -18,6 +18,7 @@ private PDashboard(com.google.protobuf.GeneratedMessageV3.Builder builder) { private PDashboard() { name_ = ""; columns_ = java.util.Collections.emptyList(); + id_ = ""; } @java.lang.Override @@ -2010,6 +2011,45 @@ public name.abuchen.portfolio.model.proto.v1.PDashboard.ColumnOrBuilder getColum return columns_.get(index); } + public static final int ID_FIELD_NUMBER = 4; + @SuppressWarnings("serial") + private volatile java.lang.Object id_ = ""; + /** + * string id = 4; + * @return The id. + */ + @java.lang.Override + public java.lang.String getId() { + java.lang.Object ref = id_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + id_ = s; + return s; + } + } + /** + * string id = 4; + * @return The bytes for id. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getIdBytes() { + java.lang.Object ref = id_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + id_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + private byte memoizedIsInitialized = -1; @java.lang.Override public final boolean isInitialized() { @@ -2036,6 +2076,9 @@ public void writeTo(com.google.protobuf.CodedOutputStream output) for (int i = 0; i < columns_.size(); i++) { output.writeMessage(3, columns_.get(i)); } + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(id_)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 4, id_); + } getUnknownFields().writeTo(output); } @@ -2062,6 +2105,9 @@ public int getSerializedSize() { size += com.google.protobuf.CodedOutputStream .computeMessageSize(3, columns_.get(i)); } + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(id_)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(4, id_); + } size += getUnknownFields().getSerializedSize(); memoizedSize = size; return size; @@ -2083,6 +2129,8 @@ public boolean equals(final java.lang.Object obj) { other.internalGetConfiguration())) return false; if (!getColumnsList() .equals(other.getColumnsList())) return false; + if (!getId() + .equals(other.getId())) return false; if (!getUnknownFields().equals(other.getUnknownFields())) return false; return true; } @@ -2104,6 +2152,8 @@ public int hashCode() { hash = (37 * hash) + COLUMNS_FIELD_NUMBER; hash = (53 * hash) + getColumnsList().hashCode(); } + hash = (37 * hash) + ID_FIELD_NUMBER; + hash = (53 * hash) + getId().hashCode(); hash = (29 * hash) + getUnknownFields().hashCode(); memoizedHashCode = hash; return hash; @@ -2264,6 +2314,7 @@ public Builder clear() { columnsBuilder_.clear(); } bitField0_ = (bitField0_ & ~0x00000004); + id_ = ""; return this; } @@ -2317,6 +2368,9 @@ private void buildPartial0(name.abuchen.portfolio.model.proto.v1.PDashboard resu result.configuration_ = internalGetConfiguration(); result.configuration_.makeImmutable(); } + if (((from_bitField0_ & 0x00000008) != 0)) { + result.id_ = id_; + } } @java.lang.Override @@ -2365,6 +2419,11 @@ public Builder mergeFrom(name.abuchen.portfolio.model.proto.v1.PDashboard other) } } } + if (!other.getId().isEmpty()) { + id_ = other.id_; + bitField0_ |= 0x00000008; + onChanged(); + } this.mergeUnknownFields(other.getUnknownFields()); onChanged(); return this; @@ -2418,6 +2477,11 @@ public Builder mergeFrom( } break; } // case 26 + case 34: { + id_ = input.readStringRequireUtf8(); + bitField0_ |= 0x00000008; + break; + } // case 34 default: { if (!super.parseUnknownField(input, extensionRegistry, tag)) { done = true; // was an endgroup tag @@ -2873,6 +2937,78 @@ public name.abuchen.portfolio.model.proto.v1.PDashboard.Column.Builder addColumn } return columnsBuilder_; } + + private java.lang.Object id_ = ""; + /** + * string id = 4; + * @return The id. + */ + public java.lang.String getId() { + java.lang.Object ref = id_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + id_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * string id = 4; + * @return The bytes for id. + */ + public com.google.protobuf.ByteString + getIdBytes() { + java.lang.Object ref = id_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + id_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string id = 4; + * @param value The id to set. + * @return This builder for chaining. + */ + public Builder setId( + java.lang.String value) { + if (value == null) { throw new NullPointerException(); } + id_ = value; + bitField0_ |= 0x00000008; + onChanged(); + return this; + } + /** + * string id = 4; + * @return This builder for chaining. + */ + public Builder clearId() { + id_ = getDefaultInstance().getId(); + bitField0_ = (bitField0_ & ~0x00000008); + onChanged(); + return this; + } + /** + * string id = 4; + * @param value The bytes for id to set. + * @return This builder for chaining. + */ + public Builder setIdBytes( + com.google.protobuf.ByteString value) { + if (value == null) { throw new NullPointerException(); } + checkByteStringIsUtf8(value); + id_ = value; + bitField0_ |= 0x00000008; + onChanged(); + return this; + } @java.lang.Override public final Builder setUnknownFields( final com.google.protobuf.UnknownFieldSet unknownFields) { diff --git a/name.abuchen.portfolio/protos/name/abuchen/portfolio/model/proto/v1/PDashboardOrBuilder.java b/name.abuchen.portfolio/protos/name/abuchen/portfolio/model/proto/v1/PDashboardOrBuilder.java index e0fb1991c5..9e7e04dad8 100644 --- a/name.abuchen.portfolio/protos/name/abuchen/portfolio/model/proto/v1/PDashboardOrBuilder.java +++ b/name.abuchen.portfolio/protos/name/abuchen/portfolio/model/proto/v1/PDashboardOrBuilder.java @@ -76,4 +76,16 @@ java.lang.String getConfigurationOrThrow( */ name.abuchen.portfolio.model.proto.v1.PDashboard.ColumnOrBuilder getColumnsOrBuilder( int index); + + /** + * string id = 4; + * @return The id. + */ + java.lang.String getId(); + /** + * string id = 4; + * @return The bytes for id. + */ + com.google.protobuf.ByteString + getIdBytes(); } diff --git a/name.abuchen.portfolio/src/name/abuchen/portfolio/model/Client.java b/name.abuchen.portfolio/src/name/abuchen/portfolio/model/Client.java index 579d7fe5c2..7151d1a626 100644 --- a/name.abuchen.portfolio/src/name/abuchen/portfolio/model/Client.java +++ b/name.abuchen.portfolio/src/name/abuchen/portfolio/model/Client.java @@ -29,7 +29,7 @@ public interface Properties // NOSONAR String WATCHLISTS = "watchlists"; //$NON-NLS-1$ } - public static final int CURRENT_VERSION = 64; + public static final int CURRENT_VERSION = 65; public static final int VERSION_WITH_CURRENCY_SUPPORT = 29; public static final int VERSION_WITH_UNIQUE_FILTER_KEY = 57; diff --git a/name.abuchen.portfolio/src/name/abuchen/portfolio/model/ClientFactory.java b/name.abuchen.portfolio/src/name/abuchen/portfolio/model/ClientFactory.java index 8665abc5c6..418bb042b1 100644 --- a/name.abuchen.portfolio/src/name/abuchen/portfolio/model/ClientFactory.java +++ b/name.abuchen.portfolio/src/name/abuchen/portfolio/model/ClientFactory.java @@ -39,6 +39,7 @@ import java.util.Objects; import java.util.Optional; import java.util.Set; +import java.util.UUID; import java.util.function.Function; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -899,10 +900,12 @@ else if (flags.contains(SaveFlag.COMPRESSED)) addInvestmentPlanTypes(client); case 61: // NOSONAR removePortfolioReportMarketProperties(client); - case 62: + case 62: // NOSONAR updateSecurityChartLabelConfiguration(client); - case 63: + case 63: // NOSONAR fixNullSecurityEvents(client); + case 64: // NOSONAR + assignDashboardIds(client); client.setVersion(Client.CURRENT_VERSION); break; @@ -1640,7 +1643,8 @@ private static void fixNullSecurityProperties(Client client) private static void fixNullSecurityEvents(Client client) { - // see https://forum.portfolio-performance.info/t/fehlermeldung-cannot-invoke-name-abuchen-portfolio-model-securityevent-gettype-because-event-is-null/29406 + // see + // https://forum.portfolio-performance.info/t/fehlermeldung-cannot-invoke-name-abuchen-portfolio-model-securityevent-gettype-because-event-is-null/29406 for (Security security : client.getSecurities()) { @@ -1702,6 +1706,13 @@ private static void updateSecurityChartLabelConfiguration(Client client) "SHOW_DATA_DIVESTMENT_INVESTMENT_LABEL,SHOW_DATA_DIVIDEND_LABEL,SHOW_DATA_EXTREMES_LABEL")); //$NON-NLS-1$ } + private static void assignDashboardIds(Client client) + { + // dashboards get a unique identifier to reliably identify them in + // configuration (say the navigation bar) + client.getDashboards().forEach(dashboard -> dashboard.setId(UUID.randomUUID().toString())); + } + private static synchronized XStream xstreamReader() { if (xstreamReader == null) diff --git a/name.abuchen.portfolio/src/name/abuchen/portfolio/model/Dashboard.java b/name.abuchen.portfolio/src/name/abuchen/portfolio/model/Dashboard.java index 872df3db8b..bed5eddcef 100644 --- a/name.abuchen.portfolio/src/name/abuchen/portfolio/model/Dashboard.java +++ b/name.abuchen.portfolio/src/name/abuchen/portfolio/model/Dashboard.java @@ -4,6 +4,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.UUID; public final class Dashboard { @@ -99,10 +100,30 @@ public Widget copy() } } + private String id; private String name; private Map configuration; private List columns; + /* package */ Dashboard() + { + } + + public Dashboard(String id) + { + this.id = id; + } + + public String getId() + { + return id; + } + + /* package */ void setId(String id) + { + this.id = id; + } + public String getName() { return name; @@ -136,7 +157,7 @@ public void setColumns(List columns) public Dashboard copy() { - Dashboard copy = new Dashboard(); + Dashboard copy = new Dashboard(UUID.randomUUID().toString()); copy.setName(this.name); copy.getConfiguration().putAll(this.getConfiguration()); diff --git a/name.abuchen.portfolio/src/name/abuchen/portfolio/model/ProtobufWriter.java b/name.abuchen.portfolio/src/name/abuchen/portfolio/model/ProtobufWriter.java index a31537aab6..6bef70b58c 100644 --- a/name.abuchen.portfolio/src/name/abuchen/portfolio/model/ProtobufWriter.java +++ b/name.abuchen.portfolio/src/name/abuchen/portfolio/model/ProtobufWriter.java @@ -680,6 +680,7 @@ private void loadDashboards(PClient newClient, Client client) for (PDashboard newDashboard : newClient.getDashboardsList()) { Dashboard dashboard = new Dashboard(); + dashboard.setId(newDashboard.getId()); dashboard.setName(newDashboard.getName()); dashboard.getConfiguration().putAll(newDashboard.getConfigurationMap()); @@ -1254,6 +1255,7 @@ private void saveDashboards(Client client, PClient.Builder newClient) client.getDashboards().forEach(dashboard -> { PDashboard.Builder newDashboard = PDashboard.newBuilder(); + newDashboard.setId(dashboard.getId()); newDashboard.setName(dashboard.getName()); newDashboard.putAllConfiguration(dashboard.getConfiguration()); diff --git a/name.abuchen.portfolio/src/name/abuchen/portfolio/model/client.proto b/name.abuchen.portfolio/src/name/abuchen/portfolio/model/client.proto index fc8deedf64..84a2d857be 100644 --- a/name.abuchen.portfolio/src/name/abuchen/portfolio/model/client.proto +++ b/name.abuchen.portfolio/src/name/abuchen/portfolio/model/client.proto @@ -257,6 +257,7 @@ message PDashboard { string name = 1; map configuration = 2; repeated Column columns = 3; + string id = 4; } message PBookmark {