27
27
using System ;
28
28
using System . Collections . Generic ;
29
29
using System . Linq ;
30
+ using System . Security ;
30
31
using MonoDevelop . Core ;
31
32
using MonoDevelop . Ide ;
33
+ using MonoDevelop . PackageManagement . Gui ;
32
34
using MonoDevelop . Projects ;
35
+ using NuGet . PackageManagement . UI ;
33
36
using NuGet . Versioning ;
34
37
using Xwt ;
35
38
using Xwt . Drawing ;
@@ -97,6 +100,8 @@ public ManagePackagesDialog (
97
100
LoadViewModel ( initialSearch ) ;
98
101
99
102
closeButton . Clicked += CloseButtonClicked ;
103
+ packageLicenseLink . NavigateToUrl += PackageLicenseNavigateToUrl ;
104
+ packageLicenseMetadataLabel . LinkClicked += PackageLicenseLinkClicked ;
100
105
this . showPrereleaseCheckBox . Clicked += ShowPrereleaseCheckBoxClicked ;
101
106
this . packageSourceComboBox . SelectionChanged += PackageSourceChanged ;
102
107
this . addPackagesButton . Clicked += AddPackagesButtonClicked ;
@@ -115,6 +120,8 @@ public ManagePackagesDialog (
115
120
protected override void Dispose ( bool disposing )
116
121
{
117
122
closeButton . Clicked -= CloseButtonClicked ;
123
+ packageLicenseLink . NavigateToUrl -= PackageLicenseNavigateToUrl ;
124
+ packageLicenseMetadataLabel . LinkClicked -= PackageLicenseLinkClicked ;
118
125
currentPackageVersionLabel . BoundsChanged -= PackageVersionLabelBoundsChanged ;
119
126
120
127
imageLoader . Loaded -= ImageLoaded ;
@@ -408,6 +415,10 @@ void ShowPackageInformation (ManagePackagesSearchResultViewModel packageViewMode
408
415
{
409
416
bool consolidate = viewModel . IsConsolidatePageSelected ;
410
417
418
+ foreach ( Widget child in packageInfoVBox . Children ) {
419
+ child . Visible = ! consolidate ;
420
+ }
421
+
411
422
if ( consolidate ) {
412
423
projectsListViewLabel . Text = GettextCatalog . GetString ( "Select projects and a version for a consolidation." ) ;
413
424
} else {
@@ -422,7 +433,7 @@ void ShowPackageInformation (ManagePackagesSearchResultViewModel packageViewMode
422
433
this . packageId . Visible = packageViewModel . HasNoGalleryUrl ;
423
434
ShowUri ( this . packageIdLink , packageViewModel . GalleryUrl , packageViewModel . Id ) ;
424
435
ShowUri ( this . packageProjectPageLink , packageViewModel . ProjectUrl ) ;
425
- ShowUri ( this . packageLicenseLink , packageViewModel . LicenseUrl ) ;
436
+ ShowLicense ( packageViewModel ) ;
426
437
427
438
PopulatePackageDependencies ( packageViewModel ) ;
428
439
}
@@ -442,10 +453,6 @@ void ShowPackageInformation (ManagePackagesSearchResultViewModel packageViewMode
442
453
packageVersionsHBox . Visible = true ;
443
454
}
444
455
445
- foreach ( Widget child in packageInfoVBox . Children ) {
446
- child . Visible = ! consolidate ;
447
- }
448
-
449
456
if ( consolidate ) {
450
457
PopulateProjectList ( ) ;
451
458
} else {
@@ -971,6 +978,7 @@ void SelectedPackageViewModelChanged (object sender, PropertyChangedEventArgs e)
971
978
} else {
972
979
if ( ! viewModel . IsConsolidatePageSelected ) {
973
980
packagePublishedDate . Text = viewModel . SelectedPackage . GetLastPublishedDisplayText ( ) ;
981
+ ShowLicense ( viewModel . SelectedPackage ) ;
974
982
PopulatePackageDependencies ( viewModel . SelectedPackage ) ;
975
983
}
976
984
}
@@ -1161,5 +1169,159 @@ void ProjectCheckBoxCellViewToggled (object sender, WidgetEventArgs e)
1161
1169
1162
1170
UpdateAddPackagesButton ( ) ;
1163
1171
}
1172
+
1173
+ void ShowLicense ( ManagePackagesSearchResultViewModel packageViewModel )
1174
+ {
1175
+ if ( packageViewModel . HasLicenseMetadata ) {
1176
+ ShowLicenseMetadata ( packageViewModel ) ;
1177
+ } else {
1178
+ packageLicenseMetadataHBox . Visible = false ;
1179
+ packageLicenseMetadataWarningsVBox . Visible = false ;
1180
+ ShowUri ( packageLicenseLink , packageViewModel . LicenseUrl , GettextCatalog . GetString ( "View License" ) ) ;
1181
+ }
1182
+ }
1183
+
1184
+ static string GetUriMarkup ( Uri uri , string text )
1185
+ {
1186
+ return string . Format (
1187
+ "<a href=\" {0}\" >{1}</a>" ,
1188
+ uri != null ? SecurityElement . Escape ( uri . ToString ( ) ) : string . Empty ,
1189
+ SecurityElement . Escape ( text ) ) ;
1190
+ }
1191
+
1192
+ void PackageLicenseNavigateToUrl ( object sender , NavigateToUrlEventArgs e )
1193
+ {
1194
+ if ( ShowLicenseFile ( e . Uri ) ) {
1195
+ e . SetHandled ( ) ;
1196
+ }
1197
+ }
1198
+
1199
+ bool ShowLicenseFile ( Uri uri )
1200
+ {
1201
+ if ( ! uri . IsFile )
1202
+ return false ;
1203
+
1204
+ if ( uri . Fragment ? . Length > 0 ) {
1205
+ if ( int . TryParse ( uri . Fragment . Substring ( 1 ) , out int fileNumber ) ) {
1206
+ ShowLicenseFile ( fileNumber ) ;
1207
+ return true ;
1208
+ }
1209
+ }
1210
+ return false ;
1211
+ }
1212
+
1213
+ void PackageLicenseLinkClicked ( object sender , LinkEventArgs e )
1214
+ {
1215
+ if ( ShowLicenseFile ( e . Target ) ) {
1216
+ e . SetHandled ( ) ;
1217
+ }
1218
+ }
1219
+
1220
+ void ShowLicenseMetadata ( ManagePackagesSearchResultViewModel packageViewModel )
1221
+ {
1222
+ List < WarningText > warnings = null ;
1223
+ var textLinks = packageViewModel . GetLicenseLinks ( ) ;
1224
+
1225
+ if ( textLinks . Count == 0 ) {
1226
+ packageLicenseLink . Visible = false ;
1227
+ packageLicenseMetadataHBox . Visible = false ;
1228
+ packageLicenseMetadataWarningsVBox . Visible = false ;
1229
+ return ;
1230
+ }
1231
+
1232
+ // Single link - show this on the same line as the License label.
1233
+ if ( textLinks . Count == 1 ) {
1234
+ packageLicenseLink . Visible = true ;
1235
+ packageLicenseMetadataHBox . Visible = false ;
1236
+ packageLicenseMetadataWarningsVBox . Visible = false ;
1237
+
1238
+ IText textLink = textLinks [ 0 ] ;
1239
+ if ( textLink is LicenseText licenseText ) {
1240
+ packageLicenseLink . Text = licenseText . Text ;
1241
+ packageLicenseLink . Uri = licenseText . Link ;
1242
+ return ;
1243
+ } else if ( textLink is LicenseFileText licenseFileText ) {
1244
+ packageLicenseLink . Text = GettextCatalog . GetString ( "View License" ) ;
1245
+ packageLicenseLink . Uri = CreateLicenseFileUri ( licenseFileText , 1 ) ;
1246
+ return ;
1247
+ } else {
1248
+ // Warning or plain text - handled below.
1249
+ }
1250
+ }
1251
+
1252
+ // Multiple text links. We need to allow these to wrap so show these below the license label.
1253
+ var markupBuilder = StringBuilderCache . Allocate ( ) ;
1254
+
1255
+ int fileLicenseCount = 0 ; // Should be one but handle multiple.
1256
+ foreach ( IText textLink in textLinks ) {
1257
+ if ( textLink is LicenseText licenseText ) {
1258
+ markupBuilder . Append ( GetUriMarkup ( licenseText . Link , licenseText . Text ) ) ;
1259
+ } else if ( textLink is LicenseFileText licenseFileText ) {
1260
+ fileLicenseCount ++ ;
1261
+ markupBuilder . Append ( GetUriMarkup ( CreateLicenseFileUri ( licenseFileText , fileLicenseCount ) , licenseFileText . Text ) ) ;
1262
+ } else if ( textLink is WarningText warning ) {
1263
+ warnings ??= new List < WarningText > ( ) ;
1264
+ warnings . Add ( warning ) ;
1265
+ } else {
1266
+ markupBuilder . Append ( textLink . Text ) ;
1267
+ }
1268
+ }
1269
+
1270
+ packageLicenseLink . Visible = false ;
1271
+ packageLicenseMetadataHBox . Visible = true ;
1272
+ packageLicenseMetadataLabel . Markup = StringBuilderCache . ReturnAndFree ( markupBuilder ) ;
1273
+
1274
+ if ( warnings != null ) {
1275
+ AddWarnings ( warnings ) ;
1276
+ } else {
1277
+ packageLicenseMetadataWarningsVBox . Visible = false ;
1278
+ }
1279
+ }
1280
+
1281
+ Uri CreateLicenseFileUri ( LicenseFileText licenseFileText , int licenseCount )
1282
+ {
1283
+ return new Uri ( $ "file:///{ licenseFileText . Text } #{ licenseCount } ") ;
1284
+ }
1285
+
1286
+ void AddWarnings ( List < WarningText > warnings )
1287
+ {
1288
+ foreach ( Widget child in packageLicenseMetadataWarningsVBox . Children . ToArray ( ) ) {
1289
+ packageLicenseMetadataWarningsVBox . Remove ( child ) ;
1290
+ child . Dispose ( ) ;
1291
+ }
1292
+
1293
+ foreach ( WarningText warning in warnings ) {
1294
+ var hbox = new HBox ( ) ;
1295
+ var image = new ImageView {
1296
+ Image = ImageService . GetIcon ( "md-warning" , Gtk . IconSize . Menu ) ,
1297
+ MarginLeft = packageLicenseMetadataLabel . MarginLeft ,
1298
+ VerticalPlacement = WidgetPlacement . Start ,
1299
+ } ;
1300
+ image . Accessible . RoleDescription = GettextCatalog . GetString ( "Warning Icon" ) ;
1301
+ hbox . PackStart ( image ) ;
1302
+
1303
+ var label = new Label {
1304
+ Text = warning . Text ,
1305
+ Font = packageLicenseMetadataLabel . Font ,
1306
+ Wrap = WrapMode . Word
1307
+ } ;
1308
+ image . Accessible . LabelWidget = label ;
1309
+ label . Accessible . LabelWidget = packageLicenseLabel ;
1310
+ hbox . PackStart ( label , true , true ) ;
1311
+
1312
+ packageLicenseMetadataWarningsVBox . PackStart ( hbox ) ;
1313
+ }
1314
+
1315
+ packageLicenseMetadataWarningsVBox . Visible = true ;
1316
+ }
1317
+
1318
+ void ShowLicenseFile ( int fileNumber )
1319
+ {
1320
+ LicenseFileText licenseFileText = viewModel . SelectedPackage . GetLicenseFile ( fileNumber ) ;
1321
+ if ( licenseFileText != null ) {
1322
+ var dialog = new LicenseFileDialog ( licenseFileText ) ;
1323
+ dialog . Run ( this ) ;
1324
+ }
1325
+ }
1164
1326
}
1165
1327
}
0 commit comments