| Index: grit/tool/resize.py
|
| ===================================================================
|
| --- grit/tool/resize.py (revision 0)
|
| +++ grit/tool/resize.py (revision 0)
|
| @@ -0,0 +1,303 @@
|
| +#!/usr/bin/python2.4
|
| +# Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
|
| +# Use of this source code is governed by a BSD-style license that can be
|
| +# found in the LICENSE file.
|
| +
|
| +'''The 'grit resize' tool.
|
| +'''
|
| +
|
| +import getopt
|
| +import os
|
| +import types
|
| +
|
| +from grit.tool import interface
|
| +from grit.tool import build
|
| +from grit import grd_reader
|
| +from grit import pseudo
|
| +from grit import util
|
| +
|
| +from grit.node import include
|
| +from grit.node import structure
|
| +from grit.node import message
|
| +
|
| +from grit.format import rc_header
|
| +
|
| +
|
| +# Template for the .vcproj file, with a couple of [[REPLACEABLE]] parts.
|
| +PROJECT_TEMPLATE = '''\
|
| +<?xml version="1.0" encoding="Windows-1252"?>
|
| +<VisualStudioProject
|
| + ProjectType="Visual C++"
|
| + Version="7.10"
|
| + Name="[[DIALOG_NAME]]"
|
| + ProjectGUID="[[PROJECT_GUID]]"
|
| + Keyword="Win32Proj">
|
| + <Platforms>
|
| + <Platform
|
| + Name="Win32"/>
|
| + </Platforms>
|
| + <Configurations>
|
| + <Configuration
|
| + Name="Debug|Win32"
|
| + OutputDirectory="Debug"
|
| + IntermediateDirectory="Debug"
|
| + ConfigurationType="1"
|
| + CharacterSet="2">
|
| + </Configuration>
|
| + </Configurations>
|
| + <References>
|
| + </References>
|
| + <Files>
|
| + <Filter
|
| + Name="Resource Files"
|
| + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
|
| + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
|
| + <File
|
| + RelativePath=".\[[DIALOG_NAME]].rc">
|
| + </File>
|
| + </Filter>
|
| + </Files>
|
| + <Globals>
|
| + </Globals>
|
| +</VisualStudioProject>'''
|
| +
|
| +
|
| +# Template for the .rc file with a couple of [[REPLACEABLE]] parts.
|
| +# TODO(joi) Improve this (and the resource.h template) to allow saving and then
|
| +# reopening of the RC file in Visual Studio. Currently you can only open it
|
| +# once and change it, then after you close it you won't be able to reopen it.
|
| +RC_TEMPLATE = '''\
|
| +// Copyright (c) Google Inc. 2005
|
| +// All rights reserved.
|
| +// This file is automatically generated by GRIT and intended for editing
|
| +// the layout of the dialogs contained in it. Do not edit anything but the
|
| +// dialogs. Any changes made to translateable portions of the dialogs will
|
| +// be ignored by GRIT.
|
| +
|
| +#include "resource.h"
|
| +#include <winresrc.h>
|
| +#ifdef IDC_STATIC
|
| +#undef IDC_STATIC
|
| +#endif
|
| +#define IDC_STATIC (-1)
|
| +
|
| +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
|
| +
|
| +#pragma code_page([[CODEPAGE_NUM]])
|
| +
|
| +[[INCLUDES]]
|
| +
|
| +[[DIALOGS]]
|
| +'''
|
| +
|
| +
|
| +# Template for the resource.h file with a couple of [[REPLACEABLE]] parts.
|
| +HEADER_TEMPLATE = '''\
|
| +// Copyright (c) Google Inc. 2005
|
| +// All rights reserved.
|
| +// This file is automatically generated by GRIT. Do not edit.
|
| +
|
| +#pragma once
|
| +
|
| +// Edit commands
|
| +#define ID_EDIT_CLEAR 0xE120
|
| +#define ID_EDIT_CLEAR_ALL 0xE121
|
| +#define ID_EDIT_COPY 0xE122
|
| +#define ID_EDIT_CUT 0xE123
|
| +#define ID_EDIT_FIND 0xE124
|
| +#define ID_EDIT_PASTE 0xE125
|
| +#define ID_EDIT_PASTE_LINK 0xE126
|
| +#define ID_EDIT_PASTE_SPECIAL 0xE127
|
| +#define ID_EDIT_REPEAT 0xE128
|
| +#define ID_EDIT_REPLACE 0xE129
|
| +#define ID_EDIT_SELECT_ALL 0xE12A
|
| +#define ID_EDIT_UNDO 0xE12B
|
| +#define ID_EDIT_REDO 0xE12C
|
| +
|
| +
|
| +[[DEFINES]]
|
| +'''
|
| +
|
| +
|
| +class ResizeDialog(interface.Tool):
|
| + '''Generates an RC file, header and Visual Studio project that you can use
|
| +with Visual Studio's GUI resource editor to modify the layout of dialogs for
|
| +the language of your choice. You then use the RC file, after you resize the
|
| +dialog, for the language or languages of your choice, using the <skeleton> child
|
| +of the <structure> node for the dialog. The translateable bits of the dialog
|
| +will be ignored when you use the <skeleton> node (GRIT will instead use the
|
| +translateable bits from the original dialog) but the layout changes you make
|
| +will be used. Note that your layout changes must preserve the order of the
|
| +translateable elements in the RC file.
|
| +
|
| +Usage: grit resize [-f BASEFOLDER] [-l LANG] [-e RCENCODING] DIALOGID*
|
| +
|
| +Arguments:
|
| + DIALOGID The 'name' attribute of a dialog to output for resizing. Zero
|
| + or more of these parameters can be used. If none are
|
| + specified, all dialogs from the input .grd file are output.
|
| +
|
| +Options:
|
| +
|
| + -f BASEFOLDER The project will be created in a subfolder of BASEFOLDER.
|
| + The name of the subfolder will be the first DIALOGID you
|
| + specify. Defaults to '.'
|
| +
|
| + -l LANG Specifies that the RC file should contain a dialog translated
|
| + into the language LANG. The default is a cp1252-representable
|
| + pseudotranslation, because Visual Studio's GUI RC editor only
|
| + supports single-byte encodings.
|
| +
|
| + -c CODEPAGE Code page number to indicate to the RC compiler the encoding
|
| + of the RC file, default is something reasonable for the
|
| + language you selected (but this does not work for every single
|
| + language). See details on codepages below. NOTE that you do
|
| + not need to specify the codepage unless the tool complains
|
| + that it's not sure which codepage to use. See the following
|
| + page for codepage numbers supported by Windows:
|
| + http://www.microsoft.com/globaldev/reference/wincp.mspx
|
| +
|
| + -D NAME[=VAL] Specify a C-preprocessor-like define NAME with optional
|
| + value VAL (defaults to 1) which will be used to control
|
| + conditional inclusion of resources.
|
| +
|
| +
|
| +IMPORTANT NOTE: For now, the tool outputs a UTF-8 encoded file for any language
|
| +that can not be represented in cp1252 (i.e. anything other than Western
|
| +European languages). You will need to open this file in a text editor and
|
| +save it using the codepage indicated in the #pragma code_page(XXXX) command
|
| +near the top of the file, before you open it in Visual Studio.
|
| +
|
| +'''
|
| +
|
| + # TODO(joi) It would be cool to have this tool note the Perforce revision
|
| + # of the original RC file somewhere, such that the <skeleton> node could warn
|
| + # if the original RC file gets updated without the skeleton file being updated.
|
| +
|
| + # TODO(joi) Would be cool to have option to add the files to Perforce
|
| +
|
| + def __init__(self):
|
| + self.lang = pseudo.PSEUDO_LANG
|
| + self.defines = {}
|
| + self.base_folder = '.'
|
| + self.codepage_number = 1252
|
| + self.codepage_number_specified_explicitly = False
|
| +
|
| + def SetLanguage(self, lang):
|
| + '''Sets the language code to output things in.
|
| + '''
|
| + self.lang = lang
|
| + if not self.codepage_number_specified_explicitly:
|
| + self.codepage_number = util.LanguageToCodepage(lang)
|
| +
|
| + def GetEncoding(self):
|
| + if self.codepage_number == 1200:
|
| + return 'utf_16'
|
| + if self.codepage_number == 65001:
|
| + return 'utf_8'
|
| + return 'cp%d' % self.codepage_number
|
| +
|
| + def ShortDescription(self):
|
| + return 'Generate a file where you can resize a given dialog.'
|
| +
|
| + def Run(self, opts, args):
|
| + self.SetOptions(opts)
|
| +
|
| + own_opts, args = getopt.getopt(args, 'l:f:c:D:')
|
| + for key, val in own_opts:
|
| + if key == '-l':
|
| + self.SetLanguage(val)
|
| + if key == '-f':
|
| + self.base_folder = val
|
| + if key == '-c':
|
| + self.codepage_number = int(val)
|
| + self.codepage_number_specified_explicitly = True
|
| + if key == '-D':
|
| + name, val = build.ParseDefine(val)
|
| + self.defines[name] = val
|
| +
|
| + res_tree = grd_reader.Parse(opts.input, debug=opts.extra_verbose)
|
| + res_tree.OnlyTheseTranslations([self.lang])
|
| + res_tree.RunGatherers(True)
|
| +
|
| + # Dialog IDs are either explicitly listed, or we output all dialogs from the
|
| + # .grd file
|
| + dialog_ids = args
|
| + if not len(dialog_ids):
|
| + for node in res_tree:
|
| + if node.name == 'structure' and node.attrs['type'] == 'dialog':
|
| + dialog_ids.append(node.attrs['name'])
|
| +
|
| + self.Process(res_tree, dialog_ids)
|
| +
|
| + def Process(self, grd, dialog_ids):
|
| + '''Outputs an RC file and header file for the dialog 'dialog_id' stored in
|
| + resource tree 'grd', to self.base_folder, as discussed in this class's
|
| + documentation.
|
| +
|
| + Arguments:
|
| + grd: grd = grd_reader.Parse(...); grd.RunGatherers()
|
| + dialog_ids: ['IDD_MYDIALOG', 'IDD_OTHERDIALOG']
|
| + '''
|
| + grd.SetOutputContext(self.lang, self.defines)
|
| +
|
| + project_name = dialog_ids[0]
|
| +
|
| + dir_path = os.path.join(self.base_folder, project_name)
|
| + if not os.path.isdir(dir_path):
|
| + os.mkdir(dir_path)
|
| +
|
| + # If this fails then we're not on Windows (or you don't have the required
|
| + # win32all Python libraries installed), so what are you doing mucking
|
| + # about with RC files anyway? :)
|
| + import pythoncom
|
| +
|
| + # Create the .vcproj file
|
| + project_text = PROJECT_TEMPLATE.replace(
|
| + '[[PROJECT_GUID]]', str(pythoncom.CreateGuid())
|
| + ).replace('[[DIALOG_NAME]]', project_name)
|
| + fname = os.path.join(dir_path, '%s.vcproj' % project_name)
|
| + self.WriteFile(fname, project_text)
|
| + print "Wrote %s" % fname
|
| +
|
| + # Create the .rc file
|
| + # Output all <include> nodes since the dialogs might depend on them (e.g.
|
| + # for icons and bitmaps).
|
| + include_items = []
|
| + for node in grd:
|
| + if isinstance(node, include.IncludeNode):
|
| + formatter = node.ItemFormatter('rc_all')
|
| + if formatter:
|
| + include_items.append(formatter.Format(node, self.lang))
|
| + rc_text = RC_TEMPLATE.replace('[[CODEPAGE_NUM]]',
|
| + str(self.codepage_number))
|
| + rc_text = rc_text.replace('[[INCLUDES]]', ''.join(include_items))
|
| +
|
| + # Then output the dialogs we have been asked to output.
|
| + dialogs = []
|
| + for dialog_id in dialog_ids:
|
| + node = grd.GetNodeById(dialog_id)
|
| + # TODO(joi) Add exception handling for better error reporting
|
| + formatter = node.ItemFormatter('rc_all')
|
| + dialogs.append(formatter.Format(node, self.lang))
|
| + rc_text = rc_text.replace('[[DIALOGS]]', ''.join(dialogs))
|
| +
|
| + fname = os.path.join(dir_path, '%s.rc' % project_name)
|
| + self.WriteFile(fname, rc_text, self.GetEncoding())
|
| + print "Wrote %s" % fname
|
| +
|
| + # Create the resource.h file
|
| + header_defines = []
|
| + for node in grd:
|
| + formatter = node.ItemFormatter('rc_header')
|
| + if formatter and not isinstance(formatter, rc_header.TopLevel):
|
| + header_defines.append(formatter.Format(node, self.lang))
|
| + header_text = HEADER_TEMPLATE.replace('[[DEFINES]]', ''.join(header_defines))
|
| + fname = os.path.join(dir_path, 'resource.h')
|
| + self.WriteFile(fname, header_text)
|
| + print "Wrote %s" % fname
|
| +
|
| + def WriteFile(self, filename, contents, encoding='cp1252'):
|
| + f = util.WrapOutputStream(file(filename, 'wb'), encoding)
|
| + f.write(contents)
|
| + f.close()
|
|
|
| Property changes on: grit/tool/resize.py
|
| ___________________________________________________________________
|
| Added: svn:eol-style
|
| + LF
|
|
|
|
|