Index: grit/tool/resize.py |
=================================================================== |
--- grit/tool/resize.py (revision 202) |
+++ grit/tool/resize.py (working copy) |
@@ -1,289 +0,0 @@ |
-#!/usr/bin/env python |
-# Copyright (c) 2012 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 |
- |
-from grit import grd_reader |
-from grit import pseudo |
-from grit import util |
-from grit.format import rc |
-from grit.format import rc_header |
-from grit.node import include |
-from grit.tool import interface |
- |
- |
-# 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 = '''\ |
-// 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 = '''\ |
-// 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 = util.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() |
- |
- # 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.SetOutputLanguage(self.lang) |
- grd.SetDefines(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.ActiveDescendants(): |
- if isinstance(node, include.IncludeNode): |
- include_items.append(rc.FormatInclude(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) |
- assert node.name == 'structure' and node.attrs['type'] == 'dialog' |
- # TODO(joi) Add exception handling for better error reporting |
- dialogs.append(rc.FormatStructure(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 = ''.join(rc_header.FormatDefines(grd)) |
- header_text = HEADER_TEMPLATE.replace('[[DEFINES]]', 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'): |
- with open(filename, 'wb') as f: |
- writer = util.WrapOutputStream(f, encoding) |
- writer.write(contents) |