MultiColumn.F90 Source File


This file depends on

sourcefile~~multicolumn.f90~~EfferentGraph sourcefile~multicolumn.f90 MultiColumn.F90 sourcefile~abstractmeternode.f90 AbstractMeterNode.F90 sourcefile~multicolumn.f90->sourcefile~abstractmeternode.f90 sourcefile~separatorcolumn.f90 SeparatorColumn.F90 sourcefile~multicolumn.f90->sourcefile~separatorcolumn.f90 sourcefile~textcolumn.f90 TextColumn.F90 sourcefile~multicolumn.f90->sourcefile~textcolumn.f90 sourcefile~textcolumnvector.f90 TextColumnVector.F90 sourcefile~multicolumn.f90->sourcefile~textcolumnvector.f90 sourcefile~abstractmeter.f90 AbstractMeter.F90 sourcefile~abstractmeternode.f90->sourcefile~abstractmeter.f90 sourcefile~separatorcolumn.f90->sourcefile~abstractmeternode.f90 sourcefile~abstractcolumn.f90 AbstractColumn.F90 sourcefile~separatorcolumn.f90->sourcefile~abstractcolumn.f90 sourcefile~simpletextcolumn.f90 SimpleTextColumn.F90 sourcefile~separatorcolumn.f90->sourcefile~simpletextcolumn.f90 sourcefile~textcolumn.f90->sourcefile~abstractmeternode.f90 sourcefile~textcolumnvector.f90->sourcefile~textcolumn.f90 sourcefile~abstractcolumn.f90->sourcefile~abstractmeternode.f90 sourcefile~distributedmeter.f90 DistributedMeter.F90 sourcefile~abstractcolumn.f90->sourcefile~distributedmeter.f90 sourcefile~errorhandling.f90 ErrorHandling.F90 sourcefile~abstractmeter.f90->sourcefile~errorhandling.f90 sourcefile~simpletextcolumn.f90->sourcefile~abstractmeternode.f90 sourcefile~simpletextcolumn.f90->sourcefile~textcolumn.f90 sourcefile~distributedmeter.f90->sourcefile~abstractmeter.f90 sourcefile~distributedmeter.f90->sourcefile~errorhandling.f90 sourcefile~abstractgauge.f90 AbstractGauge.F90 sourcefile~distributedmeter.f90->sourcefile~abstractgauge.f90 sourcefile~advancedmeter.f90 AdvancedMeter.F90 sourcefile~distributedmeter.f90->sourcefile~advancedmeter.f90 sourcefile~mapl_throw.f90 MAPL_Throw.F90 sourcefile~errorhandling.f90->sourcefile~mapl_throw.f90

Files dependent on this one

sourcefile~~multicolumn.f90~~AfferentGraph sourcefile~multicolumn.f90 MultiColumn.F90 sourcefile~mapl_profiler.f90 MAPL_Profiler.F90 sourcefile~mapl_profiler.f90->sourcefile~multicolumn.f90 sourcefile~profilereporter.f90 ProfileReporter.F90 sourcefile~mapl_profiler.f90->sourcefile~profilereporter.f90 sourcefile~profilereporter.f90->sourcefile~multicolumn.f90 sourcefile~abstractserver.f90 AbstractServer.F90 sourcefile~abstractserver.f90->sourcefile~mapl_profiler.f90 sourcefile~applicationsupport.f90 ApplicationSupport.F90 sourcefile~applicationsupport.f90->sourcefile~mapl_profiler.f90 sourcefile~base_base_implementation.f90 Base_Base_implementation.F90 sourcefile~base_base_implementation.f90->sourcefile~mapl_profiler.f90 sourcefile~demo.f90 demo.F90 sourcefile~demo.f90->sourcefile~mapl_profiler.f90 sourcefile~extdatadrivergridcomp.f90 ExtDataDriverGridComp.F90 sourcefile~extdatadrivergridcomp.f90->sourcefile~mapl_profiler.f90 sourcefile~mapl.f90 MAPL.F90 sourcefile~mapl.f90->sourcefile~mapl_profiler.f90 sourcefile~mapl_bundleio_test.f90 mapl_bundleio_test.F90 sourcefile~mapl_bundleio_test.f90->sourcefile~mapl_profiler.f90 sourcefile~mapl_capgridcomp.f90 MAPL_CapGridComp.F90 sourcefile~mapl_capgridcomp.f90->sourcefile~mapl_profiler.f90 sourcefile~mapl_generic.f90 MAPL_Generic.F90 sourcefile~mapl_generic.f90->sourcefile~mapl_profiler.f90 sourcefile~mapl_nuopcwrappermod.f90 MAPL_NUOPCWrapperMod.F90 sourcefile~mapl_nuopcwrappermod.f90->sourcefile~mapl_profiler.f90 sourcefile~mapl_verticalmethods.f90 MAPL_VerticalMethods.F90 sourcefile~mapl_verticalmethods.f90->sourcefile~mapl_profiler.f90 sourcefile~maplframework.f90 MaplFramework.F90 sourcefile~maplframework.f90->sourcefile~mapl_profiler.f90 sourcefile~mpi_demo.f90 mpi_demo.F90 sourcefile~mpi_demo.f90->sourcefile~mapl_profiler.f90 sourcefile~mpiserver.f90 MpiServer.F90 sourcefile~mpiserver.f90->sourcefile~mapl_profiler.f90 sourcefile~multigroupserver.f90 MultiGroupServer.F90 sourcefile~multigroupserver.f90->sourcefile~mapl_profiler.f90 sourcefile~regrid_util.f90 Regrid_Util.F90 sourcefile~regrid_util.f90->sourcefile~mapl_profiler.f90 sourcefile~serverthread.f90 ServerThread.F90 sourcefile~serverthread.f90->sourcefile~mapl_profiler.f90 sourcefile~test_advancedmeter.pf test_AdvancedMeter.pf sourcefile~test_advancedmeter.pf->sourcefile~mapl_profiler.f90 sourcefile~test_column.pf test_Column.pf sourcefile~test_column.pf->sourcefile~mapl_profiler.f90 sourcefile~test_distributedmeter.pf test_DistributedMeter.pf sourcefile~test_distributedmeter.pf->sourcefile~mapl_profiler.f90 sourcefile~test_exclusivecolumn.pf test_ExclusiveColumn.pf sourcefile~test_exclusivecolumn.pf->sourcefile~mapl_profiler.f90 sourcefile~test_meternode.pf test_MeterNode.pf sourcefile~test_meternode.pf->sourcefile~mapl_profiler.f90 sourcefile~test_meternodeiterator.pf test_MeterNodeIterator.pf sourcefile~test_meternodeiterator.pf->sourcefile~mapl_profiler.f90 sourcefile~test_namecolumn.pf test_NameColumn.pf sourcefile~test_namecolumn.pf->sourcefile~mapl_profiler.f90 sourcefile~test_percentagecolumn.pf test_PercentageColumn.pf sourcefile~test_percentagecolumn.pf->sourcefile~mapl_profiler.f90 sourcefile~test_profilereporter.pf test_ProfileReporter.pf sourcefile~test_profilereporter.pf->sourcefile~mapl_profiler.f90 sourcefile~test_timeprofiler.pf test_TimeProfiler.pf sourcefile~test_timeprofiler.pf->sourcefile~mapl_profiler.f90

Source Code

module MAPL_MultiColumn
   use MAPL_TextColumn
   use MAPL_TextColumnVector
   use MAPL_AbstractMeterNode
   use MAPL_SeparatorColumn
   implicit none
   private

   public :: MultiColumn

   type, extends(TextColumn) :: MultiColumn
      private
      type (TextColumnVector) :: columns
      integer :: num_rows_header = 0
      character(:), allocatable :: shared_header(:)
   contains
      procedure :: add_column
      procedure :: get_header
      procedure :: get_num_rows_header
      procedure :: get_rows
   end type MultiColumn

   interface MultiColumn
      module procedure :: new_MultiColumn
   end interface MultiColumn


contains


   function new_MultiColumn(header, separator) result(column)
      character(*), intent(in) :: header(:)
      type(MultiColumn) :: column
      character(1), optional, intent(in) :: separator

      integer :: i, w, n

      w = len(header)
      n = size(header)
      allocate(character(w) :: column%shared_header(n))
      do i = 1, n
         column%shared_header(i) = header(i)
      end do
      if (present(separator)) call column%set_separator(separator)
      column%num_rows_header = column%get_num_rows_separator()
      call column%set_width(0)

   end function new_MultiColumn


   subroutine add_column(this, column)
      class (MultiColumn), intent(inout) :: this
      class (TextColumn), intent(in) :: column

      integer :: h, h0, w

      w = this%get_width()
      
      if (this%columns%size() > 0) then
         call this%columns%push_back(SeparatorColumn(' '))
         w = w + 1
      end if
      call this%columns%push_back(column)

      h0 = size(this%shared_header) + this%get_num_rows_separator()
      h = column%get_num_rows_header()
      this%num_rows_header = max(this%num_rows_header, h0 + h)
      w = w + column%get_width()
      call this%set_width(w)

   end subroutine add_column


   recursive subroutine get_rows(this, node, rows)
      class (MultiColumn), intent(in) :: this
      class (AbstractMeterNode), target, intent(in) :: node
      character(:), allocatable, intent(out) :: rows(:)

      integer :: i, j
      integer :: w0, w1
      class(TextColumn), pointer :: c

      integer :: total_width, height
      character(:), allocatable :: column(:)

      total_width = this%get_width()
      height = node%get_num_nodes()
      
      allocate(character(total_width) :: rows(height))
      if (height == 0) return
      
      w0 = 1
      do i = 1, this%columns%size()
         
         c => this%columns%at(i)
         w1 = w0 + c%get_width() - 1
         call c%get_rows(node, column)

         do j = 1, height
            rows(j)(w0:w1) = column(j)
         end do

         w0 = w1 + 1
      end do

   end subroutine get_rows


   recursive subroutine get_header(this, header)
      class (MultiColumn), intent(in) :: this
      character(:), allocatable, intent(out) :: header(:)

      integer :: i, column_width, column_height
      integer :: w, w0, w1, h, h0, h1, h2
      integer :: total_width, total_height, shared_height
      class(TextColumn), pointer :: c
      character(:), allocatable :: column_header(:)
      integer :: n_shared

      total_width = this%get_width()
      total_height = this%num_rows_header
      n_shared = size(this%shared_header)
      shared_height = n_shared + this%get_num_rows_separator()

      allocate(character(total_width) :: header(total_height))

      header(1:n_shared) = this%shared_header
      call this%center(header(1:n_shared))
      call this%get_separator(header(n_shared+1), shared_height - n_shared)

      c => this%columns%at(1)
      column_height = c%get_num_rows_header()
      column_width = c%get_width()
      header(shared_height+1:total_height-column_height) = repeat(' ', column_width)
      call c%get_header(column_header)
      do h = 1, column_height
         h0 = total_height - column_height + h
         header(h0) = column_header(h)
      end do
      deallocate(column_header)

      w0 = 1
      do i = 1, this%columns%size()
         c => this%columns%at(i)
         column_height = c%get_num_rows_header()
         w = c%get_width()
         w1 = w0 + w - 1
         h0 = shared_height + 1
         h1 = total_height-column_height+1
         h2 = total_height

         header(h0:h1-1)(w0:w1) = repeat(' ',w)
         call c%get_header(column_header)
         header(h1:h2)(w0:w1) = column_header
         w0 = w1 + 1 ! space
         deallocate(column_header)
      end do

   end subroutine get_header
   
   integer function get_num_rows_header(this) result(num_rows)
      class(MultiColumn), intent(in) :: this
      num_rows = this%num_rows_header
   end function get_num_rows_header

end module MAPL_MultiColumn