[DRE-commits] r6051 - in branches/upstream: . webgen webgen/current webgen/current/bin webgen/current/lib webgen/current/lib/webgen webgen/current/lib/webgen/plugins webgen/current/lib/webgen/plugins/coreplugins
Vincent Fourmond
fourmond at alioth.debian.org
Mon Feb 14 18:46:46 UTC 2011
Author: fourmond
Date: 2011-02-14 18:46:37 +0000 (Mon, 14 Feb 2011)
New Revision: 6051
Added:
branches/upstream/webgen/
branches/upstream/webgen/current/
branches/upstream/webgen/current/bin/
branches/upstream/webgen/current/bin/webgen
branches/upstream/webgen/current/bin/webgen-gallery-editor
branches/upstream/webgen/current/bin/webgen-gui
branches/upstream/webgen/current/lib/
branches/upstream/webgen/current/lib/webgen.rb
branches/upstream/webgen/current/lib/webgen/
branches/upstream/webgen/current/lib/webgen/plugins/
branches/upstream/webgen/current/lib/webgen/plugins/coreplugins/
branches/upstream/webgen/current/lib/webgen/plugins/coreplugins/configuration.rb
Log:
[svn-inject] Installing original source of webgen (0.3.8)
Added: branches/upstream/webgen/current/bin/webgen
===================================================================
--- branches/upstream/webgen/current/bin/webgen (rev 0)
+++ branches/upstream/webgen/current/bin/webgen 2011-02-14 18:46:37 UTC (rev 6051)
@@ -0,0 +1,5 @@
+#!/usr/bin/env ruby
+
+require 'webgen'
+
+Webgen::cli_main
Property changes on: branches/upstream/webgen/current/bin/webgen
___________________________________________________________________
Added: svn:executable
+
Added: branches/upstream/webgen/current/bin/webgen-gallery-editor
===================================================================
--- branches/upstream/webgen/current/bin/webgen-gallery-editor (rev 0)
+++ branches/upstream/webgen/current/bin/webgen-gallery-editor 2011-02-14 18:46:37 UTC (rev 6051)
@@ -0,0 +1,654 @@
+#!/usr/bin/env ruby
+# -*- ruby -*-
+
+require 'yaml'
+require 'ostruct'
+require 'webgen/plugin'
+require 'webgen/plugins/coreplugins/configuration'
+require 'webgen/plugins/filehandlers/gallery'
+require 'Qt'
+# Error when loading Qt before RMagick -> error in RMagick undefined method `display' for class `Magick::Image'
+# report that to qtruby team and RMagick team
+
+class Gallery
+
+ attr_accessor :meta
+ attr_accessor :relpath
+
+ def initialize
+ set_default_values
+ @relpath = '.'
+ end
+
+ def []( name )
+ @meta[name]
+ end
+
+ def []=( name, value )
+ @meta[name] = value
+ end
+
+ def set_default_values
+ @meta = {}
+ Webgen::Plugin.config[FileHandlers::GalleryFileHandler].params.each do |name, data|
+ @meta[name] = data.value
+ end
+ @meta['mainPage'] = nil
+ @meta['galleryPages'] = nil
+ @meta['thumbnailSize'] = nil
+ end
+
+ def read_file( filename )
+ filedata = YAML::load( File.read( filename ) )
+
+ set_default_values
+ filedata.each {|name, data| @meta[name] = data }
+ @relpath = File.dirname( filename )
+ end
+
+ def write_file( filename )
+ File.open( filename, 'w+' ) {|file| file.write( @meta.to_yaml ) }
+ @relpath= File.dirname( filename )
+ end
+
+end
+
+
+class ImageViewer < Qt::Frame
+
+ def initialize( p )
+ super( p )
+ setFrameStyle( Qt::Frame::StyledPanel | Qt::Frame::Sunken )
+ set_image
+ end
+
+ def set_image( filename = nil)
+ filename = File.join( CorePlugins::Configuration.data_dir, 'resources/images/webgen_logo.png' ) if filename.nil?
+ @image = Qt::Image.new( filename )
+ update
+ end
+
+ def drawContents( painter )
+ return if @image.nil?
+ width = contentsRect.width
+ height = contentsRect.height
+ image = ( width > @image.width && height > @image.height ? @image : @image.smoothScale( width, height, Qt::Image::ScaleMin ) )
+ painter.drawImage( contentsRect.left + (width - image.width) / 2, contentsRect.top + (height - image.height) / 2, image )
+ end
+
+ def sizeHint
+ Qt::Size.new( 320, 200 )
+ end
+
+end
+
+
+class MetaTableNameItem < Qt::TableItem
+
+ def initialize( table, text = '' )
+ super( table, Qt::TableItem::OnTyping )
+ setReplaceable( false )
+ setText( text )
+ add_text_to_list( text )
+ end
+
+ def createEditor
+ cb = Qt::ComboBox.new( table.viewport )
+ cb.setEditable( true )
+ cb.setAutoCompletion( true )
+ cb.insertStringList( table.meta_items )
+ cb.setCurrentText( text )
+ cb
+ end
+
+ def setContentFromEditor( widget )
+ setText( widget.currentText )
+ add_text_to_list( widget.currentText )
+ end
+
+ def add_text_to_list( text )
+ unless text.nil? || text.empty? || table.meta_items.include?( text )
+ table.meta_items << text
+ table.meta_items.sort!
+ end
+ end
+
+end
+
+class MetaTableValueItem < Qt::TableItem
+
+ def initialize( table, text = '' )
+ super( table, Qt::TableItem::OnTyping )
+ setContent( text )
+ end
+
+ def setContent( content )
+ setText( content.to_s )
+ end
+
+ def getContent
+ case text
+ when 'true' then true
+ when 'false' then false
+ when 'nil' then nil
+ when /\d+/ then text.to_i
+ else text
+ end
+ end
+
+end
+
+
+class MetaDataTable < Qt::Table
+
+ slots 'value_changed(int, int)'
+
+ attr_reader :meta_items
+
+ def initialize( p, meta_items = [], exclude_items = [] )
+ super( 1, 2, p )
+ @meta_items = meta_items.sort!
+ @exclude_items = exclude_items
+ horizontalHeader.setLabel( 0, 'Name' )
+ horizontalHeader.setLabel( 1, 'Value' )
+ setSelectionMode( Qt::Table::Single )
+ setItem( 0, 0, MetaTableNameItem.new( self ) )
+ setItem( 0, 1, MetaTableValueItem.new( self ) )
+
+ connect( horizontalHeader, SIGNAL('clicked(int)'), self, SLOT('setFocus()') )
+ connect( verticalHeader, SIGNAL('clicked(int)'), self, SLOT('setFocus()') )
+ connect( self, SIGNAL('valueChanged(int, int)'), self, SLOT('value_changed( int, int )') )
+ end
+
+ def activateNextCell
+ activate = endEdit( currentRow, currentColumn, true, false )
+ oldRow = currentRow
+ oldCol = currentColumn
+
+ setCurrentCell( currentColumn == 1 ? (currentRow == numRows - 1 ? 0 : currentRow + 1) : currentRow,
+ (currentColumn + 1) % 2 )
+ setCurrentCell( oldRow, oldCol ) if !activate
+ end
+
+ def endEdit( row, col, accept, replace )
+ activate_next_cell = true
+ w = cellWidget( row, col )
+ if col == 0 && !w.nil?
+ if keys( (0...row).to_a + (row+1..numRows-1).to_a ).find {|t| t == w.currentText && t != '' }
+ msg = "You can't add duplicate entries!"
+ elsif @exclude_items.include?( w.currentText )
+ msg = "This meta information can only be defined via other controls!"
+ end
+ if msg
+ Qt::MessageBox.information( self, "Error adding entry", msg )
+ accept = false
+ activate_next_cell = false
+ end
+ end
+ super( row, col, accept, replace )
+ activate_next_cell
+ end
+
+ def fill( items )
+ setNumRows( items.length + 1 )
+ items.each_with_index do |data, index|
+ setItem( index, 0, MetaTableNameItem.new( self, data[0] ) )
+ setItem( index, 1, MetaTableValueItem.new( self, data[1] ) )
+ end
+ setItem( items.length, 0, MetaTableNameItem.new( self ) )
+ setItem( items.length, 1, MetaTableValueItem.new( self ) )
+ end
+
+ def keys( rows = (0..(numRows-1)).to_a )
+ retval = []
+ rows.each do |i|
+ retval << text( i, 0 )
+ end
+ retval
+ end
+
+ def meta_info
+ retval = {}
+ 0.upto( numRows - 2 ) do |i|
+ retval[text( i, 0 )] = item( i, 1 ).getContent
+ end
+ retval
+ end
+
+ def value_changed( row, col )
+ col0empty = text( row, 0 ).nil? || text( row, 0).empty?
+ col1empty = text( row, 1 ).nil? || text( row, 1).empty?
+ if row == numRows - 1 && (!col0empty || !col1empty)
+ setNumRows( numRows + 1 )
+ setItem( numRows - 1, 0, MetaTableNameItem.new( self ) )
+ setItem( numRows - 1, 1, MetaTableValueItem.new( self ) )
+ elsif !(row == numRows - 1) && col0empty && col1empty
+ removeRow( row )
+ end
+ end
+
+ def keyReleaseEvent( event )
+ if event.key == Qt::Key_Delete
+ if currentSelection == -1
+ setText( currentRow, currentColumn, '' )
+ emit valueChanged( currentRow, currentColumn )
+ else
+ sel = selection( currentSelection )
+ sel.topRow.upto( sel.bottomRow ) do |row|
+ sel.leftCol.upto( sel.rightCol) do |col|
+ setText( row, col, '' )
+ emit valueChanged( row, col )
+ end
+ end
+ end
+ else
+ event.ignore
+ end
+ end
+
+end
+
+
+class MyTextEdit < Qt::TextEdit
+
+ signals 'myReturnPressed()'
+
+ def keyPressEvent( event )
+ if (event.key == Qt::Key_Return || event.key == Qt::Key_Enter) && (event.state & Qt::ControlButton == Qt::ControlButton)
+ emit myReturnPressed()
+ else
+ super
+ end
+ end
+
+end
+
+
+class ImageFileDrag < Qt::DragObject
+
+ def initialize( text, parent )
+ super( parent )
+ @text = text
+ end
+
+ def format( param )
+ if param == 0
+ "app/webgen-image-file" #how to define a user mime type correctly?
+ else
+ nil
+ end
+ end
+
+ def encodedData( format )
+ @text
+ end
+
+end
+
+class ImageFileList < Qt::ListBox
+
+ def initialize( parent, mainWindow )
+ super( parent )
+ setAcceptDrops( true )
+ @dragPos = nil
+ @mainWindow = mainWindow
+ Qt::ToolTip.add( self, "You can order the images by dragging and dropping the image names (sets the <b>orderInfo</b> meta information)" )
+ end
+
+ def fill_list( items )
+ items.sort do |a,b|
+ aoi = (@mainWindow.gallery[a].nil? ? 0 : @mainWindow.gallery[a]['orderInfo'].to_s.to_i)
+ boi = (@mainWindow.gallery[b].nil? ? 0 : @mainWindow.gallery[b]['orderInfo'].to_s.to_i)
+ aoi <=> boi
+ end.each {|image| insertItem( image )}
+ end
+
+ def dragEnterEvent( event )
+ event.accept if event.provides( "app/webgen-image-file" )
+ end
+
+ def dropEvent( event )
+ text = event.encodedData( "app/webgen-image-file" ).to_s
+ dropIndex = index( itemAt( event.pos ) )
+
+ blockSignals( true )
+ @mainWindow.save_image_meta_info
+ removeItem( currentItem )
+ insertItem( text, dropIndex )
+ @mainWindow.save_image_meta_info
+ blockSignals( false )
+
+ 0.upto( count - 1 ) {|i| (@mainWindow.gallery[text( i )] ||= {})['orderInfo'] = i }
+
+ setCurrentItem( dropIndex )
+ end
+
+ def mousePressEvent( event )
+ super
+ @dragPos = event.pos
+ end
+
+ def mouseReleaseEvent( event )
+ super
+ @dragPos = nil
+ end
+
+ def mouseMoveEvent( event )
+ if @dragPos && (@dragPos - event.pos).manhattanLength > Qt::Application.startDragDistance
+ d = ImageFileDrag.new( currentText, self )
+ d.dragMove
+ @dragPos = nil
+ end
+ end
+
+end
+
+
+class GalleryWindow < Qt::MainWindow
+
+ slots 'new()', 'open()', 'save()', 'save_as()', 'image_selected(const QString &)',
+ 'init_image_list()', 'select_next_image()', "assign_pic_names()"
+
+ attr_reader :gallery
+
+ def initialize
+ super
+ setCaption( "Webgen Gallery Editor" )
+
+ @gallery = nil
+ @curfile = nil
+ setup_menus
+ setup_window
+ centralWidget.setEnabled( false )
+ end
+
+ def new
+ gallery = Gallery.new
+ if save_as( gallery )
+ @gallery = gallery
+ init_widgets
+ end
+ end
+
+ def open
+ openDialog = Qt::FileDialog.new( '.', 'Gallery files (*.gallery)', self, 'Open file...', true )
+ openDialog.setMode( Qt::FileDialog::ExistingFile )
+ open_file( openDialog.selectedFile ) if openDialog.exec == Qt::Dialog::Accepted
+ end
+
+ def open_file( file )
+ @curfile = file
+ @gallery = Gallery.new
+ @gallery.read_file( file )
+ init_widgets
+ end
+
+ def save
+ update_gallery
+ @gallery.write_file( @curfile )
+ end
+
+ def save_as( gallery = @gallery )
+ ret_val = false
+ saveDialog = Qt::FileDialog.new( '.', 'Gallery files (*.gallery)', self, 'Select new file...', true )
+ saveDialog.setMode( Qt::FileDialog::AnyFile )
+ if saveDialog.exec == Qt::Dialog::Accepted
+ fname = saveDialog.selectedFile
+ fname += '.gallery' if File.extname( fname ) == ''
+ gallery.write_file( fname )
+ @curfile = fname
+ ret_val = true
+ end
+ ret_val
+ end
+
+ def image_selected( name )
+ save_image_meta_info
+ @last_selected_image = name
+
+ if @gallery[name]
+ @imageTitle.setText( @gallery[name].delete( 'title' ) )
+ @imageDescription.setText( @gallery[name].delete( 'description' ) )
+ @picMetaTable.fill( @gallery[name] )
+ end
+ @image.set_image( File.join( @gallery.relpath, name ) )
+ end
+
+ def select_next_image
+ if @imageList.currentItem == @imageList.count - 1
+ @imageList.setCurrentItem( 0 ) if @imageList.count > 0
+ else
+ @imageList.setCurrentItem( @imageList.currentItem + 1 )
+ end
+ end
+
+ def assign_pic_names
+ 0.upto( @imageList.count - 1 ) do |i|
+ @gallery[@imageList.text( i )] ||= {}
+ if @gallery[@imageList.text( i )]['title'].to_s.empty?
+ @gallery[@imageList.text( i )]['title'] = @imageList.text( i )
+ end
+ end
+ end
+
+ def save_image_meta_info
+ if @last_selected_image
+ @gallery[@last_selected_image] = @picMetaTable.meta_info
+ @gallery[@last_selected_image]['title'] = @imageTitle.text
+ @gallery[@last_selected_image]['description'] = @imageDescription.text
+ @last_selected_image = nil
+ end
+ end
+
+ #######
+ private
+ #######
+
+ def page_meta_items
+ ['title', 'description', 'orderInfo', 'template', 'inMenu']
+ end
+
+ def gallery_items
+ ['title', 'layout', 'files', 'imagesPerPage',
+ 'imagePageInMenu', 'galleryPageInMenu', 'mainPageInMenu',
+ 'imagePageTemplate', 'galleryPageTemplate', 'mainPageTemplate',
+ 'galleryPages', 'mainPage', 'galleryOrderInfo', 'thumbnailSize' ]
+ end
+
+ def init_widgets
+ return if @gallery.nil?
+
+ gallery_items.each do |t|
+ case @widgets[t]
+ when Qt::LineEdit then @widgets[t].setText( @gallery[t] )
+ when Qt::SpinBox then @widgets[t].setValue( @gallery[t] )
+ when Qt::CheckBox then @widgets[t].setChecked( @gallery[t] )
+ when Qt::ComboBox then @widgets[t].setCurrentText( @gallery[t] )
+ when MetaDataTable then @widgets[t].fill( @gallery[t] ) if @gallery[t]
+ end
+ end
+ @picMetaTable.fill( [] )
+ init_image_list
+ @image.set_image
+ centralWidget.setEnabled( true )
+ end
+
+ def update_gallery
+ items = gallery_items
+ items.each do |t|
+ case @widgets[t]
+ when Qt::LineEdit then @gallery[t] = @widgets[t].text
+ when Qt::SpinBox then @gallery[t] = @widgets[t].value
+ when Qt::CheckBox then @gallery[t] = @widgets[t].checked?
+ when Qt::ComboBox then @gallery[t] = @widgets[t].currentText
+ when MetaDataTable then @gallery[t] = @widgets[t].meta_info
+ end
+ end
+ images = []
+ 0.upto( @imageList.numRows ) {|i| images << @imageList.text( i ) }
+
+ save_image_meta_info
+ @gallery.meta.delete_if do |name, data|
+ !images.include?( name ) && !items.include?( name )
+ end
+ end
+
+ def init_image_list
+ @imageList.clear
+ images = Dir[File.join( @gallery.relpath, @widgets['files'].text)].collect {|i| i.sub( /#{@gallery.relpath + File::SEPARATOR}/, '' ) }
+ @imageList.fill_list( images )
+ @last_selected_image = nil
+ end
+
+ def setup_menus
+ filemenu = Qt::PopupMenu.new( self )
+ filemenu.insertItem( "&New...", self, SLOT("new()"), Qt::KeySequence.new( CTRL+Key_N ) )
+ filemenu.insertItem( "&Open...", self, SLOT("open()"), Qt::KeySequence.new( CTRL+Key_O ) )
+ filemenu.insertItem( "&Save", self, SLOT("save()"), Qt::KeySequence.new( CTRL+Key_S ) )
+ filemenu.insertItem( "&Save as...", self, SLOT("save_as()") )
+ filemenu.insertItem( "&Quit", $app, SLOT("quit()"), Qt::KeySequence.new( CTRL+Key_Q ) )
+
+ picmenu = Qt::PopupMenu.new( self )
+ picmenu.insertItem( "&Assign default names", self, SLOT("assign_pic_names()") )
+
+ menubar = Qt::MenuBar.new( self )
+ menubar.insertItem( "&File", filemenu )
+ menubar.insertItem( "&Images", picmenu )
+ end
+
+ def setup_window
+ mainFrame = Qt::Widget.new( self )
+
+ @widgets = {}
+ labels = {}
+ @widgets['title'] = Qt::LineEdit.new( mainFrame )
+ labels['title'] = [0, Qt::Label.new( @widgets['title'], "Gallery title:", mainFrame )]
+
+ @widgets['files'] = Qt::LineEdit.new( mainFrame )
+ connect( @widgets['files'], SIGNAL('textChanged(const QString&)'), self, SLOT('init_image_list()') )
+ labels['files'] = [1, Qt::Label.new( @widgets['files'], "File pattern:", mainFrame )]
+
+ @widgets['layout'] = Qt::ComboBox.new( true, mainFrame )
+ @widgets['layout'].setMaximumWidth( 200 )
+ Webgen::Plugin.config[GalleryLayouters::DefaultGalleryLayouter].layouts.keys.each do |name|
+ @widgets['layout'].insertItem( Qt::Pixmap.new( File.join( CorePlugins::Configuration.data_dir, 'gallery-creator', "#{name}.png" ) ), \
+ name )
+ end
+ @widgets['layout'].listBox.setMinimumWidth( @widgets['layout'].listBox.maxItemWidth + 20 )
+ labels['layout'] = [2, Qt::Label.new( @widgets['layout'], "Gallery layout:", mainFrame )]
+
+ @widgets['imagesPerPage'] = Qt::SpinBox.new( 0, 1000, 1, mainFrame )
+ labels['imagesPerPage'] = [3, Qt::Label.new( @widgets['imagesPerPage'], "Images per page:", mainFrame )]
+
+ @widgets['galleryOrderInfo'] = Qt::SpinBox.new( 0, 1000, 1, mainFrame )
+ labels['galleryOrderInfo'] = [4, Qt::Label.new( @widgets['galleryOrderInfo'], "Start <orderInfo> for gallery pages:", mainFrame )]
+
+ @widgets['thumbnailSize'] = Qt::LineEdit.new( mainFrame )
+ @widgets['thumbnailSize'].setValidator( Qt::RegExpValidator.new( Qt::RegExp.new( "\\d+x\\d+" ), mainFrame ) )
+ labels['thumbnailSize'] = [5, Qt::Label.new( @widgets['thumbnailSize'], "Thumbnail size:", mainFrame )]
+
+ @widgets['mainPageTemplate'] = Qt::LineEdit.new( mainFrame )
+ labels['mainPageTemplate'] = [6, Qt::Label.new( @widgets['mainPageTemplate'], "Template for main page:", mainFrame )]
+
+ @widgets['galleryPageTemplate'] = Qt::LineEdit.new( mainFrame )
+ labels['galleryPageTemplate'] = [7, Qt::Label.new( @widgets['galleryPageTemplate'], "Template for gallery pages:", mainFrame )]
+
+ @widgets['imagePageTemplate'] = Qt::LineEdit.new( mainFrame )
+ labels['imagePageTemplate'] = [8, Qt::Label.new( @widgets['imagePageTemplate'], "Template for image pages:", mainFrame )]
+
+ @widgets['mainPageInMenu'] = Qt::CheckBox.new( "Main page in menu?", mainFrame )
+ labels['mainPageInMenu'] = [9, nil]
+
+ @widgets['galleryPageInMenu'] = Qt::CheckBox.new( "Gallery pages in menu?", mainFrame )
+ labels['galleryPageInMenu'] = [10, nil]
+
+ @widgets['imagePageInMenu'] = Qt::CheckBox.new( "Image pages in menu?", mainFrame )
+ labels['imagePageInMenu'] = [11, nil]
+
+ layout = Qt::GridLayout.new( @widgets.length, 2 )
+ layout.setSpacing( 5 )
+ labels.each_with_index do |data, index|
+ layout.addWidget( data[1][1], data[1][0], 0 ) if data[1][1]
+ layout.addWidget( @widgets[data[0]], data[1][0], 1 )
+ end
+
+ leftLayout = Qt::VBoxLayout.new
+ leftLayout.setSpacing( 5 )
+ leftLayout.addLayout( layout )
+ leftLayout.addStretch
+
+ @widgets['mainPage'] = MetaDataTable.new( mainFrame, page_meta_items )
+ @widgets['mainPage'].setColumnWidth( 0, 150 )
+ @widgets['mainPage'].setColumnWidth( 1, 150 )
+ @widgets['mainPage'].setMinimumWidth( 350 )
+ @widgets['galleryPages'] = MetaDataTable.new( mainFrame, page_meta_items )
+ @widgets['galleryPages'].setColumnWidth( 0, 150 )
+ @widgets['galleryPages'].setColumnWidth( 1, 150 )
+
+ rightLayout = Qt::VBoxLayout.new
+ rightLayout.setSpacing( 5 )
+ rightLayout.addWidget( Qt::Label.new( 'Meta information for main page:', mainFrame ) )
+ rightLayout.addWidget( @widgets['mainPage'] )
+ rightLayout.addWidget( Qt::Label.new( 'Meta information for gallery pages:', mainFrame ) )
+ rightLayout.addWidget( @widgets['galleryPages'] )
+
+ galLayout = Qt::HBoxLayout.new
+ galLayout.setSpacing( 20 )
+ galLayout.addLayout( leftLayout )
+ galLayout.addLayout( rightLayout )
+ galLayout.setStretchFactor( rightLayout, 1 )
+
+
+ @image = ImageViewer.new( mainFrame )
+ @image.setSizePolicy( Qt::SizePolicy::Expanding, Qt::SizePolicy::Expanding )
+ @image.setMinimumSize( 320, 200 )
+
+ @imageTitle = Qt::LineEdit.new( mainFrame )
+ imageTitle = Qt::Label.new( @imageTitle, "Title:", mainFrame )
+ @imageDescription = MyTextEdit.new( mainFrame )
+ @imageDescription.setTextFormat( Qt::PlainText )
+ imageDescription = Qt::Label.new( @imageDescription, "Description:", mainFrame )
+ connect( @imageTitle, SIGNAL('returnPressed()'), @imageDescription, SLOT('setFocus()') )
+ connect( @imageDescription, SIGNAL('myReturnPressed()'), self, SLOT('select_next_image()') )
+ connect( @imageDescription, SIGNAL('myReturnPressed()'), @imageTitle, SLOT('setFocus()') )
+
+ @imageList = ImageFileList.new( mainFrame, self )
+ @imageList.setMaximumWidth( 300 )
+ connect( @imageList, SIGNAL('highlighted(const QString &)'), self, SLOT('image_selected( const QString &)') )
+ @picMetaTable = MetaDataTable.new( mainFrame, page_meta_items - ['title', 'description'], ['title', 'description'] )
+ @picMetaTable.setColumnWidth( 0, 100 )
+ @picMetaTable.setColumnWidth( 1, 100 )
+ @picMetaTable.setMaximumWidth( 300 )
+
+ imageLayout = Qt::GridLayout.new( 3, 3 )
+ imageLayout.setSpacing( 6 )
+ imageLayout.addWidget( @imageList, 0, 0 )
+ imageLayout.addMultiCellWidget( @picMetaTable, 1, 2, 0, 0 )
+ imageLayout.addMultiCellWidget( @image, 0, 0, 1, 2 )
+ imageLayout.addWidget( imageTitle, 1, 1 )
+ imageLayout.addWidget( @imageTitle, 1, 2 )
+ imageLayout.addWidget( imageDescription, 2, 1, Qt::AlignTop )
+ imageLayout.addWidget( @imageDescription, 2, 2 )
+ imageLayout.setRowStretch( 0, 1 )
+
+ mainLayout = Qt::VBoxLayout.new( mainFrame )
+ mainLayout.setMargin( 10 )
+ mainLayout.setSpacing( 20 )
+ mainLayout.addLayout( galLayout )
+ mainLayout.addLayout( imageLayout )
+ mainLayout.setStretchFactor( imageLayout, 1 )
+
+ setCentralWidget( mainFrame )
+ end
+
+end
+
+Webgen::Plugin['Configuration'].init_all
+
+$app = Qt::Application.new( ARGV )
+mainWindow = GalleryWindow.new
+$app.setMainWidget( mainWindow )
+mainWindow.show
+mainWindow.open_file( ARGV[0] ) if ARGV.length > 0
+$app.exec
+
Added: branches/upstream/webgen/current/bin/webgen-gui
===================================================================
--- branches/upstream/webgen/current/bin/webgen-gui (rev 0)
+++ branches/upstream/webgen/current/bin/webgen-gui 2011-02-14 18:46:37 UTC (rev 6051)
@@ -0,0 +1,10 @@
+#!/usr/bin/env ruby
+# -*- ruby -*-
+
+require 'webgen/gui/main'
+
+$app = Qt::Application.new( ARGV )
+main = Webgen::GUI::MainWindow.new
+$app.setMainWidget( main )
+main.show
+$app.exec
Property changes on: branches/upstream/webgen/current/bin/webgen-gui
___________________________________________________________________
Added: svn:executable
+
Added: branches/upstream/webgen/current/lib/webgen/plugins/coreplugins/configuration.rb
===================================================================
--- branches/upstream/webgen/current/lib/webgen/plugins/coreplugins/configuration.rb (rev 0)
+++ branches/upstream/webgen/current/lib/webgen/plugins/coreplugins/configuration.rb 2011-02-14 18:46:37 UTC (rev 6051)
@@ -0,0 +1,134 @@
+#
+#--
+#
+# $Id: configuration.rb 369 2005-12-24 11:37:40Z thomas $
+#
+# webgen: template based static website generator
+# Copyright (C) 2004 Thomas Leitner
+#
+# This program is free software; you can redistribute it and/or modify it under the terms of the GNU
+# General Public License as published by the Free Software Foundation; either version 2 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along with this program; if not,
+# write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+#++
+#
+
+require 'find'
+require 'tsort'
+require 'cmdparse'
+require 'webgen/node'
+require 'webgen/plugin'
+
+# Helper class for calculating plugin dependencies.
+class Dependency < Hash
+ include TSort
+
+ alias tsort_each_node each_key
+ def tsort_each_child(node, &block)
+ fetch(node).each(&block)
+ end
+end
+
+module Webgen
+
+ VERSION = [0, 3, 8]
+ SUMMARY = "Webgen is a templated based static website generator."
+ DESCRIPTION = "Webgen is a web page generator implemented in Ruby. " \
+ "It is used to generate static web pages from templates and page " \
+ "description files."
+
+end
+
+module CorePlugins
+
+ # Responsible for loading the other plugin files and holds the basic configuration options.
+ class Configuration < Webgen::Plugin
+
+ summary "Responsible for loading plugins and holding general parameters"
+
+ add_param 'srcDirectory', 'src', 'The directory from which the source files are read.'
+ add_param 'outDirectory', 'output', 'The directory to which the output files are written.'
+ add_param 'lang', 'en', 'The default language.'
+
+ # Returns the +CommandParser+ object used for parsing the command line. You can add site
+ # specific commands to it by calling the Configuration#add_cmdparser_command method!
+ attr_accessor :cmdparser
+
+ # Returns the data directory of webgen.
+ def self.data_dir
+ unless defined?( @@data_dir )
+ @@data_dir = File.join( Config::CONFIG["datadir"], "webgen" )
+
+ if defined?( Gem::Cache )
+ gem = Gem::Cache.from_installed_gems.search( "webgen", "=#{Webgen::VERSION.join('.')}" ).last
+ @@data_dir = File.join( gem.full_gem_path, "data", "webgen" ) if gem
+ end
+
+ @@data_dir = File.dirname( $0 ) + '/../data/webgen' if !File.exists?( @@data_dir )
+
+ if File.exists?( @@data_dir )
+ logger.info { "Webgen data directory found at #{@@data_dir}" }
+ else
+ logger.error { "Could not locate webgen data directory!!!" }
+ @@data_dir = ''
+ end
+ end
+ @@data_dir
+ end
+
+ def add_cmdparser_command( command )
+ @cmdparser.add_command( command ) if @cmdparser
+ end
+
+ # Does all the initialisation stuff
+ def init_all
+ load_plugins( File.dirname( __FILE__).sub( /coreplugins$/,'' ), File.dirname( __FILE__).sub(/webgen\/plugins\/coreplugins$/, '') )
+ load_plugins( 'plugin', '' )
+ init_plugins
+ end
+
+ # Load all plugins in the given +path+. Before +require+ is actually called the path is
+ # trimmed: if +trimpath+ matches the beginning of the string, +trimpath+ is deleted from it.
+ def load_plugins( path, trimpath )
+ Find.find( path ) do |file|
+ trimmedFile = file.gsub(/^#{trimpath}/, '')
+ Find.prune unless File.directory?( file ) || ( (/.rb$/ =~ file) && !$".include?( trimmedFile ) )
+ if File.file?( file )
+ self.logger.debug { "Loading plugin file <#{file}>..." }
+ require trimmedFile
+ end
+ end
+ end
+
+ # Instantiate the plugins in the correct order, except the classes which have a constant
+ # +VIRTUAL+, and add CommandPlugin instance to the global CommandParser.
+ def init_plugins
+ dep = Dependency.new
+ Webgen::Plugin.config.each {|k,data| dep[data.plugin] = data.dependencies || []}
+ dep.tsort.each do |plugin|
+ data = Webgen::Plugin.config.find {|k,v| v.plugin == plugin }[1]
+ unless data.klass.const_defined?( 'VIRTUAL' ) || data.obj
+ self.logger.debug { "Creating plugin of class #{data.klass.name}" }
+ data.obj ||= data.klass.new
+ end
+ end
+ Webgen::Plugin.config.keys.find_all {|klass| klass.ancestors.include?( Webgen::CommandPlugin )}.each do |cmdKlass|
+ add_cmdparser_command( Webgen::Plugin.config[cmdKlass].obj )
+ end
+ end
+
+ end
+
+ # Initialize single configuration instance
+ Webgen::Plugin.config[Configuration].obj = Configuration.new
+
+end
+
+
Added: branches/upstream/webgen/current/lib/webgen.rb
===================================================================
--- branches/upstream/webgen/current/lib/webgen.rb (rev 0)
+++ branches/upstream/webgen/current/lib/webgen.rb 2011-02-14 18:46:37 UTC (rev 6051)
@@ -0,0 +1,277 @@
+#
+#--
+#
+# $Id: webgen.rb 369 2005-12-24 11:37:40Z thomas $
+#
+# webgen: template based static website generator
+# Copyright (C) 2004 Thomas Leitner
+#
+# This program is free software; you can redistribute it and/or modify it under the terms of the GNU
+# General Public License as published by the Free Software Foundation; either version 2 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along with this program; if not,
+# write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+#++
+#
+
+require 'rbconfig'
+require 'fileutils'
+require 'cmdparse'
+require 'webgen/plugin'
+require 'webgen/gui/common'
+
+
+module Webgen
+
+ class Color
+
+ @@colors = {:bold => [0, 1], :green => [0, 32], :lblue => [1, 34], :lred => [1, 31], :reset => [0, 0]}
+
+ def self.colorify
+ @@colors.each do |color, values|
+ module_eval <<-EOF
+ def Color.#{color.to_s}
+ "\e[#{values[0]};#{values[1]}m"
+ end
+ EOF
+ end
+ end
+
+ def self.method_missing( id )
+ ''
+ end
+
+ end
+
+ class CreateCommand < CmdParse::Command
+
+ def initialize
+ super( 'create', false )
+ self.short_desc = "Creates the basic directories and files for webgen"
+ self.description = "You can optionally specify a template and/or a style which should be used. " \
+ "This allows you to create a good starting template for your website."
+ self.options = CmdParse::OptionParserWrapper.new do |opts|
+ opts.separator "Options:"
+ opts.on( '-t', '--template TEMPLATE', 'Specify the template which should be used' ) {|@template|}
+ opts.on( '-s', '--style STYLE', 'Specify the style which should be used' ) {|@style|}
+ opts.separator ""
+ opts.separator "Available templates and styles:"
+ opts.separator opts.summary_indent + "Templates: " + Webgen::Website.templates.join(', ')
+ opts.separator opts.summary_indent + "Styles: " + Webgen::Website.styles.join(', ')
+ end
+ @template = 'default'
+ @style = 'default'
+ end
+
+ def usage
+ "Usage: #{commandparser.program_name} [global options] create [options] DIR"
+ end
+
+ def execute( args )
+ if args.length == 0
+ raise OptionParser::MissingArgument.new( 'DIR' )
+ else
+ Webgen.create_website( args[0], @template, @style )
+ end
+ end
+
+ end
+
+ class CleanCommand < CmdParse::Command
+
+ module ::FileUtils
+
+ def fu_output_message( msg )
+ logger.info { msg }
+ end
+
+ def ask_before_delete( ask, func, list, options = {} )
+ newlist = [*list].collect {|e| "'" + e + "'"}.join(', ')
+ if ask
+ print "Really delete #{newlist}? "
+ return unless /y|Y/ =~ gets.strip
+ end
+ self.send( func, list, options.merge( :verbose => true ) )
+ end
+
+ module_function :ask_before_delete
+
+ end
+
+ class CleanWalker < Webgen::Plugin
+
+ summary "Deletes the output file for each node."
+ depends_on 'TreeWalker'
+
+ attr_writer :ask
+
+ def handle_node( node, level )
+ file = node.recursive_value( 'dest' )
+ return if !File.exists?( file ) || node['int:virtualNode']
+ if File.directory?( file )
+ begin
+ FileUtils.ask_before_delete( @ask, :rmdir, file )
+ rescue Errno::ENOTEMPTY => e
+ logger.info "Cannot delete directory #{file}, as it is not empty!"
+ end
+ else
+ FileUtils.ask_before_delete( @ask, :rm, file, :force => true )
+ end
+ end
+
+ end
+
+ def initialize;
+ super( 'clean', false )
+ self.short_desc = "Removes the generated or all files from the output directory"
+ self.options = CmdParse::OptionParserWrapper.new do |opts|
+ opts.separator( "Options" )
+ opts.on( '--all', '-a', "Removes ALL files from the output directory" ) { @all = true }
+ opts.on( '--interactive', '-i', "Ask for each file" ) { @ask = true }
+ end
+ @all = false
+ @ask = false
+ end
+
+ def execute( args )
+ if @all
+ logger.info( "Deleting all files from output directory..." )
+ outDir = Plugin['Configuration']['outDirectory']
+ FileUtils.ask_before_delete( @ask, :rm_rf, outDir ) if File.exists?( outDir )
+ else
+ tree = Plugin['FileHandler'].build_tree
+ logger.info( "Deleting generated files from output directory..." )
+ Plugin['CleanWalker'].ask = @ask
+ Plugin['TreeWalker'].execute( tree, Plugin['CleanWalker'], :backward )
+ end
+ logger.info( "Webgen finished 'clean' command" )
+ end
+
+ end
+
+ class WebgenCommandParser < CmdParse::CommandParser
+
+ def initialize
+ super( true )
+ self.program_name = "webgen"
+ self.program_version = Webgen::VERSION
+ self.options = CmdParse::OptionParserWrapper.new do |opts|
+ opts.separator "Global options:"
+ opts.on( "--verbosity LEVEL", "-V", Integer, "The verbosity level" ) { |verbosity| Plugin.set_param( 'Logging', 'verbosityLevel', verbosity ) }
+ opts.on( "--[no-]logfile", "-L", "Log to file" ) { |logfile| Plugin.set_param( 'Logging', 'logToFile', logfile ) }
+ end
+
+ # Run command
+ run = CmdParse::Command.new( 'run', false )
+ run.short_desc = "Runs webgen"
+ run.set_execution_block {|args| Webgen.run_webgen }
+ self.add_command( run, true )
+
+ # Show command
+ show = CmdParse::Command.new( 'show', true )
+ show.short_desc = "Show various information"
+ self.add_command( show )
+
+ # Show plugins command
+ showPlugins = CmdParse::Command.new( 'plugins', false )
+ showPlugins.short_desc = "Show the available plugins"
+ showPlugins.set_execution_block do |args|
+ print "List of loaded plugins:\n"
+
+ headers = Hash.new {|h,k| h[k] = (k.nil? ? "Other Plugins" : k.gsub(/([A-Z][a-z])/, ' \1').strip) }
+
+ ljustlength = 30 + Color.green.length + Color.reset.length
+ header = ''
+ Plugin.config.sort { |a, b| a[0].name <=> b[0].name }.each do |klass, data|
+ newHeader = headers[klass.name[/^.*?(?=::)/]]
+ unless newHeader == header
+ print "\n #{Color.bold}#{newHeader}#{Color.reset}:\n";
+ header = newHeader
+ end
+ print " - #{Color.green}#{data.plugin}#{Color.reset}:".ljust(ljustlength) +"#{data.summary}\n"
+ end
+ end
+ show.add_command( showPlugins )
+
+ # Show params command
+ showConfig = CmdParse::Command.new( 'config', false )
+ showConfig.short_desc = "Show the parameters of all plugins or of the specified one"
+ showConfig.set_execution_block do |args|
+ puts "List of plugin parameters:"
+ puts
+ ljustlength = 25 + Color.green.length + Color.reset.length
+ Plugin.config.sort { |a, b| a[0].name[/\w*$/] <=> b[0].name[/\w*$/] }.each do |klass, data|
+ next if args.length > 0 && args[0] != data.plugin
+ puts " #{Color.bold}#{data.plugin}#{Color.reset}:"
+ puts " #{Color.green}Summary:#{Color.reset}".ljust(ljustlength) + data.summary if data.summary
+ puts " #{Color.green}Description:#{Color.reset}".ljust(ljustlength) + data.description if data.description
+ puts " #{Color.green}Tag name:#{Color.reset}".ljust(ljustlength) + (data.tag == :default ? "Default tag" : data.tag) if data.tag
+ puts " #{Color.green}Handled paths:#{Color.reset}".ljust(ljustlength) + data.path.inspect if data.path
+
+ data.table.keys.find_all {|k| /^registered_/ =~ k.to_s }.each do |k|
+ name = k.to_s.sub( /^registered_/, '' ).tr('_', ' ').capitalize + " name"
+ puts " #{Color.green}#{name}:#{Color.reset}".ljust(ljustlength) + data.send( k )
+ end
+
+ if data.params
+ puts "\n #{Color.green}Parameters:#{Color.reset}"
+ data.params.sort.each do |key, item|
+ print " #{Color.green}Parameter:#{Color.reset}".ljust(ljustlength)
+ puts Color.lred + item.name + Color.reset + " = " + Color.lblue + item.value.inspect + Color.reset + " (" + item.default.inspect + ")"
+ puts " #{Color.green}Description:#{Color.reset}".ljust(ljustlength) + item.description
+ puts
+ end
+ end
+ puts
+ end
+ end
+ show.add_command( showConfig )
+
+ self.add_command( CreateCommand.new )
+ self.add_command( CleanCommand.new )
+ self.add_command( CmdParse::HelpCommand.new )
+ self.add_command( CmdParse::VersionCommand.new )
+ end
+
+ end
+
+ # Run webgen
+ def self.run_webgen( directory = Dir.pwd )
+ Dir.chdir( directory )
+
+ logger.info "Starting Webgen..."
+ tree = Plugin['FileHandler'].build_tree
+ Plugin['TreeWalker'].execute( tree ) unless tree.nil?
+ Plugin['FileHandler'].write_tree( tree ) unless tree.nil?
+ logger.info "Webgen finished"
+ end
+
+ # Create a website in the +directory+, using the +template+ and the +style+.
+ def self.create_website( directory, template = 'default', style = 'default' )
+ templateDir = File.join( CorePlugins::Configuration.data_dir, 'website_templates', template )
+ styleDir = File.join( CorePlugins::Configuration.data_dir, 'website_styles', style )
+ raise ArgumentError.new( "Invalid template <#{template}>" ) if !File.directory?( templateDir )
+ raise ArgumentError.new( "Invalid style <#{style}>" ) if !File.directory?( styleDir )
+
+ raise ArgumentError.new( "Website directory <#{directory}> does already exist!") if File.exists?( directory )
+ FileUtils.mkdir( directory )
+ FileUtils.cp_r( Dir[File.join( templateDir, '*' )], directory )
+ FileUtils.cp_r( Dir[File.join( styleDir, '*' )], File.join( directory, 'src' ) )
+ end
+
+ # Main program for the webgen CLI command.
+ def self.cli_main
+ Color.colorify if $stdout.isatty && !Config::CONFIG['arch'].include?( 'mswin32' )
+ Plugin['Configuration'].cmdparser = WebgenCommandParser.new
+ Plugin['Configuration'].cmdparser.parse do |level, cmdName|
+ Plugin['Configuration'].init_all if level == 0
+ end
+ end
+
+end
More information about the Pkg-ruby-extras-commits
mailing list