mercurial/HGChangesetList.st
changeset 398 65dc8645e496
child 399 abafe12d47d6
equal deleted inserted replaced
395:fc0607653d8a 398:65dc8645e496
       
     1 "
       
     2 stx:libscm - a new source code management library for Smalltalk/X
       
     3 Copyright (C) 2012-2013 Jan Vrany
       
     4 
       
     5 This library is free software; you can redistribute it and/or
       
     6 modify it under the terms of the GNU Lesser General Public
       
     7 License as published by the Free Software Foundation; either
       
     8 version 2.1 of the License. 
       
     9 
       
    10 This library is distributed in the hope that it will be useful,
       
    11 but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    13 Lesser General Public License for more details.
       
    14 
       
    15 You should have received a copy of the GNU Lesser General Public
       
    16 License along with this library; if not, write to the Free Software
       
    17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
       
    18 "
       
    19 "{ Package: 'stx:libscm/mercurial' }"
       
    20 
       
    21 ApplicationModel subclass:#HGChangesetList
       
    22 	instanceVariableNames:'repositoryHolder revsetHolder changesetList changesetHolder
       
    23 		changesetIndexHolder'
       
    24 	classVariableNames:''
       
    25 	poolDictionaries:''
       
    26 	category:'SCM-Mercurial-StX-Interface'
       
    27 !
       
    28 
       
    29 Object subclass:#ListEntry
       
    30 	instanceVariableNames:'changeset'
       
    31 	classVariableNames:'PaddingLeft PaddingRight PaddingTop PaddingBottom'
       
    32 	poolDictionaries:''
       
    33 	privateIn:HGChangesetList
       
    34 !
       
    35 
       
    36 !HGChangesetList class methodsFor:'documentation'!
       
    37 
       
    38 copyright
       
    39 "
       
    40 stx:libscm - a new source code management library for Smalltalk/X
       
    41 Copyright (C) 2012-2013 Jan Vrany
       
    42 
       
    43 This library is free software; you can redistribute it and/or
       
    44 modify it under the terms of the GNU Lesser General Public
       
    45 License as published by the Free Software Foundation; either
       
    46 version 2.1 of the License. 
       
    47 
       
    48 This library is distributed in the hope that it will be useful,
       
    49 but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    50 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    51 Lesser General Public License for more details.
       
    52 
       
    53 You should have received a copy of the GNU Lesser General Public
       
    54 License along with this library; if not, write to the Free Software
       
    55 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
       
    56 "
       
    57 ! !
       
    58 
       
    59 !HGChangesetList class methodsFor:'interface specs'!
       
    60 
       
    61 windowSpec
       
    62     "This resource specification was automatically generated
       
    63      by the UIPainter of ST/X."
       
    64 
       
    65     "Do not manually edit this!! If it is corrupted,
       
    66      the UIPainter may not be able to read the specification."
       
    67 
       
    68     "
       
    69      UIPainter new openOnClass:HGChangesetList andSelector:#windowSpec
       
    70      HGChangesetList new openInterface:#windowSpec
       
    71      HGChangesetList open
       
    72     "
       
    73 
       
    74     <resource: #canvas>
       
    75 
       
    76     ^ 
       
    77     #(FullSpec
       
    78        name: windowSpec
       
    79        window: 
       
    80       (WindowSpec
       
    81          label: 'HG Changeset List'
       
    82          name: 'HG Changeset List'
       
    83          min: (Point 10 10)
       
    84          bounds: (Rectangle 0 0 300 300)
       
    85        )
       
    86        component: 
       
    87       (SpecCollection
       
    88          collection: (
       
    89           (SelectionInListModelViewSpec
       
    90              name: 'SelectionInListModelView1'
       
    91              layout: (LayoutFrame 0 0 0 0 0 1 0 1)
       
    92              model: changesetIndexHolder
       
    93              hasHorizontalScrollBar: true
       
    94              hasVerticalScrollBar: true
       
    95              listModel: changesetList
       
    96              highlightMode: line
       
    97            )
       
    98           )
       
    99         
       
   100        )
       
   101      )
       
   102 ! !
       
   103 
       
   104 !HGChangesetList methodsFor:'accessing'!
       
   105 
       
   106 repository
       
   107     ^ self repositoryHolder value
       
   108 
       
   109     "Created: / 11-03-2014 / 20:54:57 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   110 !
       
   111 
       
   112 repository: anHGRepository
       
   113     self repositoryHolder value: anHGRepository
       
   114 
       
   115     "Created: / 11-03-2014 / 20:54:51 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   116 !
       
   117 
       
   118 revset
       
   119     ^ self revsetHolder value
       
   120 
       
   121     "Created: / 11-03-2014 / 20:55:06 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   122 !
       
   123 
       
   124 revset: anHGRevset
       
   125     ^ self revsetHolder value: anHGRevset
       
   126 
       
   127     "Created: / 11-03-2014 / 20:55:13 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   128 ! !
       
   129 
       
   130 !HGChangesetList methodsFor:'aspects'!
       
   131 
       
   132 changesetHolder
       
   133     "return/create the 'changesetHolder' value holder (automatically generated)"
       
   134 
       
   135     changesetHolder isNil ifTrue:[
       
   136         changesetHolder := ValueHolder new.
       
   137         changesetHolder addDependent:self.
       
   138     ].
       
   139     ^ changesetHolder
       
   140 !
       
   141 
       
   142 changesetHolder:something
       
   143     "set the 'changesetHolder' value holder (automatically generated)"
       
   144 
       
   145     |oldValue newValue|
       
   146 
       
   147     changesetHolder notNil ifTrue:[
       
   148         oldValue := changesetHolder value.
       
   149         changesetHolder removeDependent:self.
       
   150     ].
       
   151     changesetHolder := something.
       
   152     changesetHolder notNil ifTrue:[
       
   153         changesetHolder addDependent:self.
       
   154     ].
       
   155     newValue := changesetHolder value.
       
   156     oldValue ~~ newValue ifTrue:[
       
   157         self update:#value with:newValue from:changesetHolder.
       
   158     ].
       
   159 !
       
   160 
       
   161 changesetIndexHolder
       
   162     "return/create the 'changesetIndexHolder' value holder (automatically generated)"
       
   163 
       
   164     changesetIndexHolder isNil ifTrue:[
       
   165         changesetIndexHolder := ValueHolder new.
       
   166         changesetIndexHolder addDependent:self.
       
   167     ].
       
   168     ^ changesetIndexHolder
       
   169 !
       
   170 
       
   171 changesetIndexHolder:something
       
   172     "set the 'changesetIndexHolder' value holder (automatically generated)"
       
   173 
       
   174     |oldValue newValue|
       
   175 
       
   176     changesetIndexHolder notNil ifTrue:[
       
   177         oldValue := changesetIndexHolder value.
       
   178         changesetIndexHolder removeDependent:self.
       
   179     ].
       
   180     changesetIndexHolder := something.
       
   181     changesetIndexHolder notNil ifTrue:[
       
   182         changesetIndexHolder addDependent:self.
       
   183     ].
       
   184     newValue := changesetIndexHolder value.
       
   185     oldValue ~~ newValue ifTrue:[
       
   186         self update:#value with:newValue from:changesetIndexHolder.
       
   187     ].
       
   188 !
       
   189 
       
   190 changesetList
       
   191     changesetList isNil ifTrue:[
       
   192         changesetList := List new.
       
   193     ].
       
   194     ^ changesetList
       
   195 
       
   196     "Modified: / 11-03-2014 / 20:26:20 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   197 !
       
   198 
       
   199 repositoryHolder
       
   200     "return/create the 'repositoryHolder' value holder (automatically generated)"
       
   201 
       
   202     repositoryHolder isNil ifTrue:[
       
   203         repositoryHolder := ValueHolder new.
       
   204         repositoryHolder addDependent:self.
       
   205     ].
       
   206     ^ repositoryHolder
       
   207 !
       
   208 
       
   209 repositoryHolder:something
       
   210     "set the 'repositoryHolder' value holder (automatically generated)"
       
   211 
       
   212     |oldValue newValue|
       
   213 
       
   214     repositoryHolder notNil ifTrue:[
       
   215         oldValue := repositoryHolder value.
       
   216         repositoryHolder removeDependent:self.
       
   217     ].
       
   218     repositoryHolder := something.
       
   219     repositoryHolder notNil ifTrue:[
       
   220         repositoryHolder addDependent:self.
       
   221     ].
       
   222     newValue := repositoryHolder value.
       
   223     oldValue ~~ newValue ifTrue:[
       
   224         self update:#value with:newValue from:repositoryHolder.
       
   225     ].
       
   226 !
       
   227 
       
   228 revsetHolder
       
   229     "return/create the 'revsetHolder' value holder (automatically generated)"
       
   230 
       
   231     revsetHolder isNil ifTrue:[
       
   232         revsetHolder := ValueHolder new.
       
   233         revsetHolder addDependent:self.
       
   234     ].
       
   235     ^ revsetHolder
       
   236 !
       
   237 
       
   238 revsetHolder:something
       
   239     "set the 'revsetHolder' value holder (automatically generated)"
       
   240 
       
   241     |oldValue newValue|
       
   242 
       
   243     revsetHolder notNil ifTrue:[
       
   244         oldValue := revsetHolder value.
       
   245         revsetHolder removeDependent:self.
       
   246     ].
       
   247     revsetHolder := something.
       
   248     revsetHolder notNil ifTrue:[
       
   249         revsetHolder addDependent:self.
       
   250     ].
       
   251     newValue := revsetHolder value.
       
   252     oldValue ~~ newValue ifTrue:[
       
   253         self update:#value with:newValue from:revsetHolder.
       
   254     ].
       
   255 ! !
       
   256 
       
   257 !HGChangesetList methodsFor:'change & update'!
       
   258 
       
   259 delayedUpdate: aspect with: param from: sender 
       
   260 
       
   261     sender == repositoryHolder ifTrue:[
       
   262         self updateList.
       
   263     ].
       
   264 
       
   265     sender == revsetHolder ifTrue:[ 
       
   266         self updateList.
       
   267     ].
       
   268     super delayedUpdate:aspect with:param from:sender
       
   269 
       
   270     "Created: / 11-03-2014 / 20:34:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   271 !
       
   272 
       
   273 update:aspect with:param from:sender
       
   274     "Invoked when an object that I depend upon sends a change notification."
       
   275 
       
   276     sender == repositoryHolder ifTrue:[ 
       
   277         self delayedUpdate: aspect with: param from: sender 
       
   278     ].
       
   279     sender == revsetHolder ifTrue:[ 
       
   280         self delayedUpdate: aspect with: param from: sender 
       
   281     ].
       
   282 
       
   283     sender == changesetIndexHolder ifTrue:[ 
       
   284         self updateAfterChangesetIndexHolderChanged.
       
   285     ].
       
   286     sender == changesetHolder ifTrue:[ 
       
   287         self updateAfterChangesetHolderChanged.
       
   288     ].
       
   289 
       
   290 
       
   291     super update:aspect with:param from:sender
       
   292 
       
   293     "Modified: / 11-03-2014 / 20:29:14 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   294 !
       
   295 
       
   296 updateAfterChangesetHolderChanged
       
   297     | index changeset |
       
   298 
       
   299     changeset := changesetHolder value.
       
   300     index  :=(changeset notNil) 
       
   301                     ifTrue:[ self changesetList findFirst: [:e | e changeset = changeset ] ifNone:[ nil ] ]
       
   302                     ifFalse:[ nil ].
       
   303     self changesetIndexHolder 
       
   304         removeDependent: self;
       
   305         value: index;
       
   306         addDependent: self.
       
   307 
       
   308     "Created: / 11-03-2014 / 20:29:14 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   309 !
       
   310 
       
   311 updateAfterChangesetIndexHolderChanged
       
   312     | index changeset |
       
   313 
       
   314     index := changesetIndexHolder value.
       
   315     changeset :=(index notNil and:[ index ~~ 0 ]) 
       
   316                     ifTrue:[ (self changesetList at: index) changeset  ]
       
   317                     ifFalse:[ nil ].
       
   318     self changesetHolder 
       
   319         removeDependent: self;
       
   320         value: changeset;
       
   321         addDependent: self.
       
   322 
       
   323     "Created: / 11-03-2014 / 20:29:13 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   324 !
       
   325 
       
   326 updateList
       
   327     self changesetList removeAll.
       
   328     self updateList1.
       
   329 
       
   330     "Created: / 11-03-2014 / 20:34:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   331 !
       
   332 
       
   333 updateList1
       
   334     self updateListWithLimit: 10.
       
   335     self window sensor pushUserEvent: #updateList2 for: self.
       
   336 
       
   337     "Created: / 11-03-2014 / 20:36:46 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   338 !
       
   339 
       
   340 updateList2
       
   341     self updateListWithLimit: nil
       
   342 
       
   343     "Created: / 11-03-2014 / 20:38:02 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   344 !
       
   345 
       
   346 updateListWithLimit:limitOrNil
       
   347     | repository revset changesets entries |
       
   348 
       
   349     repository := self repositoryHolder value.
       
   350     repository isNil ifTrue:[
       
   351         ^ self.
       
   352     ].
       
   353     revset := self revsetHolder value.
       
   354     revset isNil ifTrue:[ 
       
   355         ^ self.
       
   356     ].
       
   357     changesets := repository log: revset limit: limitOrNil.
       
   358     entries := changesets collect:[:e | ListEntry new changeset: e ].
       
   359     self changesetList. "/ make sure it's initialized.
       
   360 
       
   361     (entries size > changesetList size and:[entries startsWith: changesetList]) ifTrue:[ 
       
   362         changesetList addAll: entries from: changesetList size + 1 to: entries size beforeIndex: changesetList size + 1
       
   363     ] ifFalse:[ 
       
   364         changesetList notEmpty ifTrue:[ 
       
   365             changesetList removeAll.
       
   366         ].
       
   367         changesetList addAll: entries from: 1 to: entries size beforeIndex: 1
       
   368     ].
       
   369 
       
   370     "Created: / 11-03-2014 / 20:37:53 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   371 ! !
       
   372 
       
   373 !HGChangesetList::ListEntry class methodsFor:'initialization'!
       
   374 
       
   375 initialize
       
   376     "Invoked at system start or when the class is dynamically loaded."
       
   377 
       
   378     "/ please change as required (and remove this comment)
       
   379 
       
   380     PaddingLeft := 3.
       
   381     PaddingRight := 3.
       
   382     PaddingTop := 3.
       
   383     PaddingBottom := 3.
       
   384 
       
   385     "Modified: / 11-03-2014 / 21:27:12 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   386 ! !
       
   387 
       
   388 !HGChangesetList::ListEntry methodsFor:'accessing'!
       
   389 
       
   390 changeset
       
   391     ^ changeset
       
   392 !
       
   393 
       
   394 changeset:anHGChangeset
       
   395     changeset := anHGChangeset.
       
   396 ! !
       
   397 
       
   398 !HGChangesetList::ListEntry methodsFor:'accessing - presentation'!
       
   399 
       
   400 authorString
       
   401     ^ changeset author
       
   402 
       
   403     "Created: / 11-03-2014 / 21:49:06 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   404 !
       
   405 
       
   406 changesetString
       
   407     ^ changeset id asString
       
   408 !
       
   409 
       
   410 dateString
       
   411     ^ changeset timestamp printString
       
   412 
       
   413     "Created: / 11-03-2014 / 21:48:22 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   414 !
       
   415 
       
   416 parentsString
       
   417     "raise an error: this method should be implemented (TODO)"
       
   418 
       
   419     | p1 p2 |
       
   420 
       
   421     p1 := changeset parent1.
       
   422     p1 isNil ifTrue:[ 
       
   423         ^ HGChangesetId null printString.
       
   424     ].
       
   425 
       
   426     p2 := changeset parent2.
       
   427     ^ p2 isNil ifTrue:[ 
       
   428         p1 id asString.
       
   429     ] ifFalse:[ 
       
   430         p1 id asString , ', ' , p2 id asString.
       
   431     ].
       
   432 
       
   433     "Created: / 11-03-2014 / 21:52:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   434 !
       
   435 
       
   436 summaryString
       
   437     ^ changeset summary
       
   438 
       
   439     "Created: / 11-03-2014 / 21:49:01 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   440 ! !
       
   441 
       
   442 !HGChangesetList::ListEntry methodsFor:'comparing'!
       
   443 
       
   444 = another
       
   445     ^ changeset = another changeset
       
   446 
       
   447     "Created: / 11-03-2014 / 21:18:58 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   448 !
       
   449 
       
   450 hash
       
   451     ^ changeset hash
       
   452 
       
   453     "Created: / 11-03-2014 / 21:18:42 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   454 ! !
       
   455 
       
   456 !HGChangesetList::ListEntry methodsFor:'displaying'!
       
   457 
       
   458 displayOn:aGC x:x0 y:y0 
       
   459     | x  y  lineH  labelW  resources |
       
   460 
       
   461     resources := HGChangesetList resources.
       
   462     lineH := ((aGC font onDevice:aGC device) height * 1.2) rounded.
       
   463     labelW := (aGC widthOfString:(resources string:'changeset')) + 30. "px"
       
   464     x := x0 + PaddingLeft.
       
   465     y := y0 + PaddingTop.
       
   466 
       
   467     (resources string:'changeset') displayOn: aGC x:x          y:y.               
       
   468     self changesetString           displayOn: aGC x:x + labelW y:y.
       
   469     y := y + lineH.
       
   470     "/ Make the rest bit indented so it's easy to
       
   471     "/ find beggining of next entry...
       
   472     x := x + 10.
       
   473     labelW := labelW - 10.
       
   474 
       
   475 
       
   476     (resources string:'user')      displayOn: aGC x:x          y:y.               
       
   477     self authorString              displayOn: aGC x:x + labelW y:y.
       
   478     y := y + lineH.
       
   479 
       
   480     (resources string:'date')      displayOn: aGC x:x          y:y.               
       
   481     self dateString                displayOn: aGC x:x + labelW y:y.
       
   482     y := y + lineH.
       
   483 
       
   484     changeset parent2 isNil ifTrue:[ 
       
   485         (resources string:'parent')  displayOn: aGC x:x          y:y.           
       
   486     ] ifFalse:[ 
       
   487         (resources string:'parents') displayOn: aGC x:x          y:y.           
       
   488     ].
       
   489     self parentsString               displayOn: aGC x:x + labelW y:y.
       
   490     y := y + lineH.
       
   491 
       
   492     (resources string:'summary')  displayOn: aGC x:x          y:y.               
       
   493     self summaryString            displayOn: aGC x:x + labelW y:y.
       
   494     y := y + lineH.
       
   495 
       
   496     "Created: / 11-03-2014 / 21:36:46 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   497 !
       
   498 
       
   499 heightOn:aGC
       
   500     | fontH lineH |
       
   501 
       
   502     fontH := (aGC font onDevice:aGC device) height.
       
   503     lineH := (fontH * 1.2) rounded.
       
   504     "
       
   505      changeset
       
   506      user:
       
   507      date:
       
   508      parents:
       
   509      summary:
       
   510      "
       
   511      ^ (lineH * 5) + PaddingTop + PaddingRight.
       
   512 
       
   513     "Created: / 11-03-2014 / 21:29:46 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   514 ! !
       
   515 
       
   516 
       
   517 HGChangesetList::ListEntry initialize!