Skip to content

Commit

Permalink
- Added support for opening ll_net and .g files
Browse files Browse the repository at this point in the history
- Improved and debugged Llnet parser: now supports reading layout information from ll_net files
- Fixed incorrect marking parser in DotGParser
- Removed dynamically reconfigurable plugin support, configuration is now done via main class (DefaultConfiguration in Workcraft project)
- Fixed incorrect shut down behaviour that caused Workcraft to never quit when launched as a sub-process
  • Loading branch information
mechkg committed Apr 13, 2012
1 parent 695a15a commit e6f4f73
Show file tree
Hide file tree
Showing 25 changed files with 274 additions and 142 deletions.
3 changes: 2 additions & 1 deletion Core/src/main/scala/org/workcraft/services/Format.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ object Format {
case object LolaPetriNet extends Format("Petri Net in LoLA format", ".lola")
case object WorkcraftPetriNet extends Format("Petri Net in Workcraft format", ".pn")
case object Dot extends Format("GraphViz dot", ".dot")
}
case object Llnet extends Format("Petri Net in PEP tool format", ".ll_net")
}
4 changes: 1 addition & 3 deletions Core/src/main/scala/org/workcraft/services/Module.scala
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package org.workcraft.services

import org.workcraft.pluginmanager.Plugin

trait Module extends Plugin {
trait Module {
def name: String
def description: String = name
def serviceProvider: GlobalServiceProvider
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
package org.workcraft.services
import org.workcraft.pluginmanager.PluginManager

class GlobalServiceManager (val modules: List[Module]) extends GlobalServiceProvider {
val serviceProviders = modules.map(_.serviceProvider)

def implementations[T] (service: Service[GlobalScope, T]) = serviceProviders.flatMap(_.implementations(service)).toList
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ object FSMServiceProvider extends GlobalServiceProvider {
}
}

class PetrifyModule extends Module {
class FSMModule extends Module {
def name = "Finite State Machine"
def serviceProvider = FSMServiceProvider
}
6 changes: 3 additions & 3 deletions Gui/src/main/scala/org/workcraft/gui/CreateWorkDialog.scala
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import java.awt.Font
import org.workcraft.scala.effects.IO
import org.workcraft.scala.effects.IO._

class CreateWorkDialog private (models: List[NewModelImpl]) extends JDialog {
class CreateWorkDialog private (models: List[NewModelImpl], owner: Window) extends JDialog(owner) {
class ListElement(val newModel: NewModelImpl) {
override def toString = newModel.name
}
Expand Down Expand Up @@ -157,10 +157,10 @@ object CreateWorkDialog {
JOptionPane.showMessageDialog(parentWindow, "Workcraft was unable to find any plug-ins that could create a new model.\n\nReconfiguring Workcraft (Utility->Reconfigure) might fix this.\n\nIf you are running Workcraft from a development environment such as Eclipse,\nplease make sure to add the plug-in classes to the classpath in run configuration. ", "Warning", JOptionPane.WARNING_MESSAGE)
None
} else {
val dialog = new CreateWorkDialog(models)
val dialog = new CreateWorkDialog(models, parentWindow)
GUI.centerAndSizeToParent(dialog, parentWindow)
dialog.setVisible(true)
dialog.choice.map((_,dialog.chkOpen.isSelected()))
}
}
}
}
14 changes: 7 additions & 7 deletions Gui/src/main/scala/org/workcraft/gui/FileMenu.scala
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import scalaz.Scalaz._
import org.workcraft.services.ExportError
import javax.swing.JOptionPane

class FileMenu(services: () => GlobalServiceManager, mainWindow: MainWindow, newModel: ((NewModelImpl, Boolean)) => IO[Unit]) extends ReactiveMenu("File") {
class FileMenu(services: GlobalServiceManager, mainWindow: MainWindow, newModel: ((NewModelImpl, Boolean)) => IO[Unit]) extends ReactiveMenu("File") {
def handleExportError(error: Option[ExportError]): IO[Unit] = error match {
case None => IO.Empty
case Some(error) => ioPure.pure { JOptionPane.showMessageDialog(mainWindow, error match { case ExportError.Exception(e) => e.toString(); case ExportError.Message(m) => m }, "Error", JOptionPane.ERROR_MESSAGE) }
Expand All @@ -39,17 +39,17 @@ class FileMenu(services: () => GlobalServiceManager, mainWindow: MainWindow, new
// Must be lazy because Scala allows to read uninitialized values
lazy val items = mainWindow.editorInFocus.map(editor => {
val newWork = menuItem("New work", Some('N'), Some(KeyStroke.getKeyStroke(KeyEvent.VK_N, ActionEvent.CTRL_MASK)),
CreateWorkDialog.show(services().implementations(NewModelService), mainWindow) >>= { case Some(choice) => newModel(choice); case None => IO.Empty })
CreateWorkDialog.show(services.implementations(NewModelService), mainWindow) >>= { case Some(choice) => newModel(choice); case None => IO.Empty })

val open = menuItem("Open file...", Some('O'), Some(KeyStroke.getKeyStroke(KeyEvent.VK_O, ActionEvent.CTRL_MASK)), OpenDialog.open(mainWindow, services()) >>= { case Some(model) => mainWindow.openEditor(model); case None => IO.Empty })
val open = menuItem("Open file...", Some('O'), Some(KeyStroke.getKeyStroke(KeyEvent.VK_O, ActionEvent.CTRL_MASK)), OpenDialog.open(mainWindow, services) >>= { case Some(model) => mainWindow.openEditor(model); case None => IO.Empty })

val save = editor match {
case Some(e) => {
val save = menuItem("Save", Some('S'), Some(KeyStroke.getKeyStroke(KeyEvent.VK_S, ActionEvent.CTRL_MASK)), SaveDialog.saveAs(mainWindow, e.content.model, services()) >>= {
val save = menuItem("Save", Some('S'), Some(KeyStroke.getKeyStroke(KeyEvent.VK_S, ActionEvent.CTRL_MASK)), SaveDialog.saveAs(mainWindow, e.content.model, services) >>= {
case Some(job) => job >>= handleExportError
case None => IO.Empty
})
val saveAs = menuItem("Save as...", Some('a'), None, SaveDialog.saveAs(mainWindow, e.content.model, services()) >>= { case Some(job) => job >>= handleExportError; case None => IO.Empty })
val saveAs = menuItem("Save as...", Some('a'), None, SaveDialog.saveAs(mainWindow, e.content.model, services) >>= { case Some(job) => job >>= handleExportError; case None => IO.Empty })
List(save, saveAs)
}
case None => {
Expand Down Expand Up @@ -85,7 +85,7 @@ class FileMenu(services: () => GlobalServiceManager, mainWindow: MainWindow, new
case Some(e) => {
val defaultFormat = e.content.model.implementation(DefaultFormatService)

val exporters = services().implementations(ExporterService).map(exp => (exp.targetFormat, exp.export(e.content.model)))
val exporters = services.implementations(ExporterService).map(exp => (exp.targetFormat, exp.export(e.content.model)))
.flatMap({ case (format, Right(job)) if (defaultFormat.map(_ != format).getOrElse(true)) => Some((format, job)); case _ => None })

exportMenu(e.content.model, exporters)
Expand All @@ -99,4 +99,4 @@ class FileMenu(services: () => GlobalServiceManager, mainWindow: MainWindow, new
})

setMnemonic('F')
}
}
8 changes: 4 additions & 4 deletions Gui/src/main/scala/org/workcraft/gui/GUI.scala
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import java.awt.Insets
import java.awt.Dimension

object GUI {
def loadImageFromResource(path: String): Either[Throwable, BufferedImage] = ClassLoader.getSystemResource(path) match {
def loadImageFromResource(path: String): Either[Throwable, BufferedImage] = this.getClass().getClassLoader().getResource(path) match {
case null => Left(new IOException("Resource not found: " + path))
case url => try { Right(ImageIO.read(url)) } catch { case e => Left(e) }
}
Expand Down Expand Up @@ -57,7 +57,7 @@ object GUI {
}

def createIconFromImage(resourcePath: String): IO[Option[ImageIcon]] = ioPure.pure {
val res = ClassLoader.getSystemResource(resourcePath)
val res = this.getClass().getClassLoader().getResource(resourcePath)
if (res == null)
None
else
Expand All @@ -73,7 +73,7 @@ object GUI {
val parser = XMLResourceDescriptor.getXMLParserClassName()
val f = new SAXSVGDocumentFactory(parser)

val document = f.createDocument(ClassLoader.getSystemResource(path).toString())
val document = f.createDocument(this.getClass().getClassLoader().getResource(path).toString())

val userAgentAdapter = new UserAgentAdapter()
val bridgeContext = new BridgeContext(userAgentAdapter)
Expand Down Expand Up @@ -154,4 +154,4 @@ object GUI {
val lm = g.getFont().getLineMetrics(message, g.getFontRenderContext())
g.drawString(message, r.x, r.y + r.height - lm.getDescent().toInt)
})
}
}
59 changes: 21 additions & 38 deletions Gui/src/main/scala/org/workcraft/gui/Main.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package org.workcraft.gui
import java.awt.Window
import org.workcraft.logging.StandardStreamLogger
import org.workcraft.pluginmanager.PluginManager
import java.util.UUID
import org.workcraft.services.GlobalServiceManager
import org.workcraft.services.Module
Expand All @@ -24,9 +24,7 @@ object Main {

implicit val logger = () => currentLogger

val version = UUID.fromString("dd10f600-4769-11e1-b86c-0800200c9a66")
val configDirPath = System.getProperty("user.home") + File.separator + ".workcraft"
val pluginPackages = List("org.workcraft.plugins")

def configFilePath(fileName: String) = configDirPath + File.separator + fileName

Expand All @@ -44,34 +42,12 @@ object Main {
unsafeInfo("Configuration directory OK")
}

private def shutdown(mainWindow: MainWindow)(implicit logger: () => Logger[IO]) = {
currentLogger = new StandardStreamLogger
unsafeInfo("Shutting down")

GuiConfiguration.save(configFilePath("gui.conf"), mainWindow.guiConfiguration)

mainWindow.setVisible(false)

unsafeInfo("Have a nice day!")
System.exit(0)
}

def loadPlugins(reconfigure: Boolean) = new PluginManager(version, pluginPackages, configFilePath("manifest"), reconfigure)

def main(args: Array[String]) = {
def main(configDescription: String, globalServices: GlobalServiceManager, args: Array[String]) = {
unsafeInfo("Welcome to Workcraft 2.2: Return of The Deadlock")
unsafeInfo("This build's version ID is " + version.toString())
unsafeInfo("This build is using " + configDescription)

checkConfig

var pluginManager = loadPlugins(false)
var globalServices = new GlobalServiceManager(pluginManager.plugins(classOf[Module]).map(_.singleton).toList)

val reconfigure = ioPure.pure {
pluginManager = loadPlugins(true)
globalServices = new GlobalServiceManager(pluginManager.plugins(classOf[Module]).map(_.singleton).toList)
}

unsafeInfo("Starting GUI")
val guiConfiguration = GuiConfiguration.load(configFilePath("gui.conf"))

Expand All @@ -81,22 +57,29 @@ object Main {
JDialog.setDefaultLookAndFeelDecorated(true)
UIManager.put(SubstanceLookAndFeel.TABBED_PANE_CONTENT_BORDER_KIND, TabContentPaneBorderKind.SINGLE_FULL)

SwingUtilities.invokeLater(new Runnable {
def run = {

val mainWindow = new MainWindow(() => globalServices, reconfigure, shutdown, guiConfiguration)
var mainWindow:MainWindow = null

mainWindow.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE)
mainWindow.addWindowListener(new WindowAdapter() {
override def windowClosing(e: WindowEvent) = shutdown(mainWindow)
})
SwingUtilities.invokeAndWait(new Runnable {
def run = {
mainWindow = new MainWindow(globalServices, guiConfiguration)

currentLogger = mainWindow.loggerWindow

unsafeInfo("Now in GUI mode. Welcome to Workcraft 2.2: Return of The Deadlock!")

mainWindow.setVisible(true)
}
})
}})

mainWindow.synchronized {
mainWindow.wait()
}

currentLogger = new StandardStreamLogger

unsafeInfo("Shutting down")

GuiConfiguration.save(configFilePath("gui.conf"), mainWindow.guiConfiguration)

unsafeInfo("Have a nice day!")
}
}
}
15 changes: 6 additions & 9 deletions Gui/src/main/scala/org/workcraft/gui/MainMenu.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,18 @@ import javax.swing.JComponent
import org.workcraft.scala.effects.IO

class MainMenu(
mainWindow: MainWindow, utilityWindows: List[DockableWindow[_ <: JComponent]],
services: () => GlobalServiceManager,
newModel: ((NewModelImpl, Boolean)) => IO[Unit],
reconfigure: IO[Unit]) extends JMenuBar {
mainWindow: MainWindow,
utilityWindows: List[DockableWindow[_ <: JComponent]],
services: GlobalServiceManager,
newModel: ((NewModelImpl, Boolean)) => IO[Unit]
) extends JMenuBar {
val fileMenu = new FileMenu(services, mainWindow, newModel)
val editMenu = new EditMenu(mainWindow)
val windowsMenu = new UtilityWindowsMenu(utilityWindows)
val toolsMenu = new ToolsMenu(services, mainWindow)
val utilityMenu = new JMenu("Utility")
utilityMenu.setMnemonic('U')
utilityMenu.add(GUI.menuItem("Reconfigure", Some('R'), None, reconfigure))

add(fileMenu)
add(editMenu)
add(windowsMenu)
add(toolsMenu)
add(utilityMenu)
}
}
24 changes: 18 additions & 6 deletions Gui/src/main/scala/org/workcraft/gui/MainWindow.scala
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,19 @@ import java.awt.event.FocusListener
import java.awt.event.FocusEvent

class MainWindow(
val globalServices: () => GlobalServiceManager,
reconfigure: IO[Unit],
shutdown: MainWindow => Unit,
val globalServices: GlobalServiceManager,
configuration: Option[GuiConfiguration]) extends JFrame {
val loggerWindow = new LoggerWindow
implicit val implicitLogger: () => Logger[IO] = () => loggerWindow


setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE)

addWindowListener(new WindowAdapter() {
override def windowClosing(e: WindowEvent) = exit.unsafePerformIO
})


applyIconManager

applyGuiConfiguration(configuration)
Expand Down Expand Up @@ -83,7 +89,7 @@ class MainWindow(

var openEditors = List[DockableWindow[ModelEditorPanel]]()

val menu = new MainMenu(this, List(loggerDockable, toolboxDockable, propEdDockable), globalServices, { case (m, b) => newModel(m, b) }, reconfigure)
val menu = new MainMenu(this, List(loggerDockable, toolboxDockable, propEdDockable), globalServices, { case (m, b) => newModel(m, b) })
this.setJMenuBar(menu)

def closeUtilityWindow(window: DockableWindow[_ <: JComponent]) = {
Expand Down Expand Up @@ -187,5 +193,11 @@ class MainWindow(
DockingManager.undock(editorDockable)
}

def exit = ioPure.pure { shutdown(this) }
}
def exit = ioPure.pure {
setVisible(false)
dispose()
this.synchronized {
notify()
}
}
}
6 changes: 3 additions & 3 deletions Gui/src/main/scala/org/workcraft/gui/ToolsMenu.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ import org.workcraft.scala.effects.IO
import javax.swing.JMenu
import org.workcraft.gui.GUI._

class ToolsMenu(services: () => GlobalServiceManager, mainWindow: MainWindow) extends ReactiveMenu("Tools") {
class ToolsMenu(services: GlobalServiceManager, mainWindow: MainWindow) extends ReactiveMenu("Tools") {
// Must be lazy because Scala allows to read uninitialized values
lazy val items = {
val applicableTools = services().implementations(GuiToolService).map(tool => tool.run(mainWindow).map(_.map((tool, _)))).traverse(x => x).map(_.flatten)
val applicableTools = services.implementations(GuiToolService).map(tool => tool.run(mainWindow).map(_.map((tool, _)))).traverse(x => x).map(_.flatten)

val makeMenu = (name: String, tools: List[(GuiTool, IO[Unit])]) => {
val result = new JMenu(name)
Expand All @@ -23,4 +23,4 @@ class ToolsMenu(services: () => GlobalServiceManager, mainWindow: MainWindow) ex
}

setMnemonic('T')
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
package org.workcraft.gui.modeleditor
import java.awt.event.HierarchyEvent
import java.awt.event.HierarchyListener
import javax.swing.JPanel
import org.workcraft.dependencymanager.advanced.core.ExpressionBase
import org.workcraft.dependencymanager.advanced.core.GlobalCache
Expand Down Expand Up @@ -36,12 +38,12 @@ class ModelEditorPanel (val model: ModelServiceProvider, val editor: ModelEditor

object Repainter {
class Image
def start = {
val repainter = graphicalContent.map(_ => { ModelEditorPanel.this.repaint(); new Image })
new Timer(30, new ActionListener {
override def actionPerformed(e: ActionEvent) = repainter.unsafeEval
}).start
}

val repainter = graphicalContent.map(_ => { ModelEditorPanel.this.repaint(); new Image })

val timer = new Timer(30, new ActionListener {
override def actionPerformed(e: ActionEvent) = repainter.unsafeEval
})
}

object Resizer extends ComponentAdapter {
Expand Down Expand Up @@ -145,8 +147,21 @@ class ModelEditorPanel (val model: ModelServiceProvider, val editor: ModelEditor

})

Repainter.start

addComponentListener(new ComponentAdapter {
override def componentShown (e:ComponentEvent) = { println ("shown!"); Repainter.timer.start; }
override def componentHidden (e:ComponentEvent) = { println ("hidden"); Repainter.timer.stop; }
})

addHierarchyListener ( new HierarchyListener {
override def hierarchyChanged (e: HierarchyEvent) =
if ((e.getChangeFlags & HierarchyEvent.SHOWING_CHANGED) != 0) {
if (isShowing)
Repainter.timer.start
else
Repainter.timer.stop
}
})

override def paint(g: Graphics) = {
val g2d = g.asInstanceOf[Graphics2D] // woohoo
graphicalContent.unsafeEval.draw(g2d)
Expand Down
Loading

0 comments on commit e6f4f73

Please sign in to comment.